2013-09-30 60 views
5

我有一个抽象模型MVC属性的抽象属性

public abstract class Treasure { 
    public abstract int Value { get; } 
    public abstract string Label { get; } 
} 

和实施

public class Coins : Treasure { 
    [DisplayName("Coin Value")] 
    public override int Value { 
     get { ... } 
    } 

    [DisplayName("Coins")] 
    public override string Label { 
     get { ... } 
    } 

我的硬币对象不显示“钱币”作为其在我看来标签,当我用Html.LabelFor上它显示“标签”。如果我将DisplayName属性移动到Treasure中,它可以工作......但我需要能够为Treasure类的不同实现更改标签。这可能吗?

+0

什么是在视图中的模型...宝藏或硬币? – CrazyDart

+0

您是否尝试过在Treasure对象和Coins对象上实现默认值?只是一个想法。 –

+0

为了清楚起见,最好能看到包含“LabelFor”的Razor标记片段。 –

回答

4

我能够得到这个工作正常,如果在视图中的模型是硬币。但是,如果模型是宝藏,它会失败。为什么?因为当Html Helper呈现Html时,它只会查看视图中指定的模型类型,而不是实际对象的对象类型。当它获取属性时,它只会获得Treasure属性而不是Coins属性。我想你必须为此编写自己的Html帮手。

internal static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string labelText, IDictionary<string, object> htmlAttributes, ModelMetadataProvider metadataProvider) 
{ 
    return LabelExtensions.LabelHelper((HtmlHelper) html, ModelMetadata.FromLambdaExpression<TModel, TValue>(expression, html.ViewData, metadataProvider), ExpressionHelper.GetExpressionText((LambdaExpression) expression), labelText, htmlAttributes); 
} 

在幕后,MVC使用ModelMetadata.FromLambdaExpression<TModel, TValue>找到“显示名称”,当它未能找到一个在...它返回PropertyName通过型式。

internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, string labelText = null, IDictionary<string, object> htmlAttributes = null) 
{ 
    string str = labelText; 
    if (str == null) 
    { 
    string displayName = metadata.DisplayName; 
    if (displayName == null) 
    { 
     string propertyName = metadata.PropertyName; 
     if (propertyName == null) 
     str = Enumerable.Last<string>((IEnumerable<string>) htmlFieldName.Split(new char[1] 
     { 
      '.' 
     })); 
     else 
     str = propertyName; 
    } 
    else 
     str = displayName; 
    } 
    string innerText = str; 
    if (string.IsNullOrEmpty(innerText)) 
    return MvcHtmlString.Empty; 
    TagBuilder tagBuilder1 = new TagBuilder("label"); 
    tagBuilder1.Attributes.Add("for", TagBuilder.CreateSanitizedId(html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName))); 
    tagBuilder1.SetInnerText(innerText); 
    TagBuilder tagBuilder2 = tagBuilder1; 
    bool flag = true; 
    IDictionary<string, object> attributes = htmlAttributes; 
    int num = flag ? 1 : 0; 
    tagBuilder2.MergeAttributes<string, object>(attributes, num != 0); 
    return TagBuilderExtensions.ToMvcHtmlString(tagBuilder1, TagRenderMode.Normal); 
} 
+0

用代码很好的解释。实际上,它看起来并不是实际类型的“@ model”声明。 –