2

2 つの複雑な型をラップする ViewModel があります。

public class EditProductViewModel
{
    public ProductData ProductData { get; set; }
    public FridgeContent FridgeContent { get; set; }
}

そしてこのビュー:

@model EditProductViewModel
@using (Html.BeginForm("Edit", "ProductData", FormMethod.Post))
{
   @Html.EditorForModel()
   [...]
}

ProductData と FridgeContent には、次のような DataAnnotations を持つ POCO プロパティが含まれています。

public class FridgeContentMetadata : DatabaseEntityMetadataBase
{
    [Required]
    [HiddenInput(DisplayValue = false)]
    public int ProductDataId { get; set; }

    [Required]
    [UIHint("StringReadOnly")]
    public int ScaleId { get; set; }

    [Required]
    [UIHint("StringReadOnly")]
    [Range(0.01, float.MaxValue, ErrorMessage = "The weight of a product must be positive.")]
    public float Weight { get; set; }

    [...]
}

これらのクラスと EditorForModel() メソッドからの適切なデータ注釈を使用して、EditProductView で ProductData と FridgeContent の両方を編集したい (自分でテンプレートを生成したくない)。したがって、ProductData.cshtml と FridgeContent.cshtml のテンプレートを /Views/Shared/EditorTemplates/ に作成しました。

@model FridgeContent 
@Html.EditorForModel()

残念ながら、EditProductViewModel のビューは空です (エラーは発生しません)。FridgeContent または ProductData のいずれかに単独で EditorForModel を使用すると、正常に動作します。[UIHint("..")] 注釈を EditProductViewModel に追加しようとしましたが、違いはありません。

私は何が欠けていますか?

4

2 に答える 2

2
@model EditProductViewModel
@using (Html.BeginForm("Edit", "ProductData", FormMethod.Post))
{
   @Html.EditorFor(o=> o.ProductData )

   @Html.EditorFor(o=> o.FridgeContent )
}

または、これらの 2 行を含む ViewModel の編集テンプレートを作成します

   @Html.EditorFor(o=> o.ProductData )
   @Html.EditorFor(o=> o.FridgeContent )

アップデート:

レンダリングエンジンはオブジェクト階層で1ステップ以上進まないため、ようやくわかりました。asp.net mvcコードでも見つけることができます。

ここでMVC 3.0ソースコードを確認してください:

DefaultEditorTemplates.csこのメソッドを含む名前のファイルがあります。

internal static string ObjectTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) {
    ViewDataDictionary viewData = html.ViewContext.ViewData;
    TemplateInfo templateInfo = viewData.TemplateInfo;
    ModelMetadata modelMetadata = viewData.ModelMetadata;
    StringBuilder builder = new StringBuilder();

    if (templateInfo.TemplateDepth > 1) {    // DDB #224751
        return modelMetadata.Model == null ? modelMetadata.NullDisplayText : modelMetadata.SimpleDisplayText;
    }

    foreach (ModelMetadata propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo))) {
        if (!propertyMetadata.HideSurroundingHtml) {
            string label = LabelExtensions.LabelHelper(html, propertyMetadata, propertyMetadata.PropertyName).ToHtmlString();
            if (!String.IsNullOrEmpty(label)) {
                builder.AppendFormat(CultureInfo.InvariantCulture, "<div class=\"editor-label\">{0}</div>\r\n", label);
            }

            builder.Append("<div class=\"editor-field\">");
        }

        builder.Append(templateHelper(html, propertyMetadata, propertyMetadata.PropertyName, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */));

        if (!propertyMetadata.HideSurroundingHtml) {
            builder.Append(" ");
            builder.Append(html.ValidationMessage(propertyMetadata.PropertyName));
            builder.Append("</div>\r\n");
        }
    }

    return builder.ToString();
}

TemplateDepth > 1これは、単純なテキストをレンダリングするだけであると明確に述べています。

于 2012-01-06T12:12:30.857 に答える
0

上記の回答が示すように、この問題は、考慮されるネストの深さを制限するフレームワークに関連しているようです。

この問題を回避する 1 つの方法は、独自のエディター テンプレートを使用することです。で部分ビュー を作成しObject.cshtmlますViews/Shared/EditorTemplateshereから取得したテンプレートの例を次に示します。

@{
    Func<ModelMetadata, bool> ShouldShow = metadata =>
        metadata.ShowForEdit && !ViewData.TemplateInfo.Visited(metadata);
}
@if (ViewData.TemplateInfo.TemplateDepth > 5) {
    if (Model == null) { 
        @ViewData.ModelMetadata.NullDisplayText 
    } else { 
        @ViewData.ModelMetadata.SimpleDisplayText 
    } 
} else {     
    foreach (var prop in ViewData.ModelMetadata.Properties.Where(ShouldShow)) { 
        if (prop.HideSurroundingHtml) { 
            @Html.Editor(prop.PropertyName) 
        } else { 
            if (string.IsNullOrEmpty(Html.Label(prop.PropertyName).ToHtmlString())==false) { 
                <div class="editor-label">
                    @Html.Label(prop.PropertyName) 
                </div>
            } 
            <div class="editor-field">
                @Html.Editor(prop.PropertyName)  
                @Html.ValidationMessage(prop.PropertyName) 
            </div>
        } 
    } 
} 

5上記の例では、定数を変更することでネストの深さの最大値を設定できます。

于 2014-07-04T02:14:39.177 に答える