I have an abstract Model
public abstract class Treasure {
public abstract int Value { get; }
public abstract string Label { get; }
}
and an implementation
public class Coins : Treasure {
[DisplayName("Coin Value")]
public override int Value {
get { ... }
}
[DisplayName("Coins")]
public override string Label {
get { ... }
}
My coins object does not show "Coins" as its label in my view when I use Html.LabelFor
on it, it shows "Label". If I move the DisplayName attribute into Treasure, it works... but I need to be able to change the label for different implementations of the Treasure class. Is this possible?
I was able to get this to work fine if the model in the view is Coins. However if the model is Treasure, it fails. Why? Because when the Html Helper renders the Html it only looks at the model type that is specified in the view, not the object type of the actual object. When it goes to get the attribute it will only get the attribute for Treasure and not Coins. I think you would have to write your own Html helper for this.
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);
}
Under the covers, MVC uses ModelMetadata.FromLambdaExpression<TModel, TValue>
to find the "DisplayName" and when it fails to find one on the type passed in... it returns the 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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With