2013-09-30 62 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」聲明。 –