EditorTemplates和ViewData

时间:2014-06-17 17:29:47

标签: asp.net-mvc mvc-editor-templates

我有大量符合Label:Control常用格式的表单。我决定不使用以下页面:

<div class="row-fluid">
     <div class="span4">
        @Html.LabelFor(m => m.Prop1)
    </div>
    <div class="span8">
       @Html.TextBoxFor(m => m.Prop1)
    </div>
</div>

我会创建一个编辑器模板来保存这个模式,并选择正确的默认控件。当然,一个队友立即指出硬编码跨度没有帮助,所以我添加了一些自定义ViewData字段,如“labelSpan”。

真正的问题是:

 @Html.TextBoxFor(m => m, new { @class = @ViewData["class"], style = @ViewData["style"], 
id = @ViewData["id"]... etc })

问题1:如何在不必指定每个属性的情况下将其合并直接传递?

问题2:我如何以下列方式不冲突?

@Html.LabelFor(m => m, new { @class = @ViewData["LabelClass"], style = @ViewData["LabelStyle"] })

1 个答案:

答案 0 :(得分:0)

您不想使用ViewData,而是希望使用ModelMetadata。如果您创建自定义ModelMetadataProvider,则可以覆盖CreateMetadata方法以将适当的值添加到AdditionalAttributes,然后您可以稍后查询这些值。

    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes,
                                                    Type containerType, Func<object> modelAccessor,
                                                    Type modelType, string propertyName)
    {
        var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
        var labelSpan = "span4"; // do whatever logic you need to.
        metadata.AdditionalValues.Add("labelSpan", labelSpan);
        ...
        return metadata;
    }

然后在编辑器模板中使用元数据。我发现的模式只是将标签放在Object.cshtml编辑器模板中:

@{
    var visibleProperties = ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit && !ViewData.TemplateInfo.Visited(pm)).ToList();
    var noHtmlProps = visibleProperties.Where(pm => pm.HideSurroundingHtml).ToList();
    var normalProperties = visibleProperties.Where(pm => !pm.HideSurroundingHtml).ToList();
    foreach (var prop in normalProperties)
    {
        <div class="row-fluid">
            @Html.Label(prop.PropertyName, prop.DisplayName, 
                new{@class=ViewData.ModelMetadata.AdditionalValues["labelSpan"]})

            @(prop.IsReadOnly 
                ? Html.Display(prop.PropertyName) 
                : Html.Editor(prop.PropertyName))
            @Html.ValidationMessage(prop.PropertyName)
        </div>
    }
    // Output hidden properties at the end
    foreach (var prop in noHtmlProps)
    {
        @Html.Editor(prop.PropertyName)
    } 
}

然后你使用其他类型&#39;编辑器模板,以确定使用哪个控件。例如,String.cshtml可能如下所示:

@Html.TextBox(string.Empty, ViewData.TemplateInfo.FormattedModelValue,
    new{@class = ViewData.ModelMetadata.AdditionalValues["valueSpan"]})