I have a model class, with a property like this:
[Display(Name = \"Phone\", Description=\"Hello World!\")]
public string Phone1 { get; set; }
@ViewData.ModelMetadata.Properties
.Where(m => m.PropertyName == "Phone1").FirstOrDefault().Description
So, if you were using bootstrap, something like
<div class="form-group col-sm-6">
@Html.LabelFor(m => m.Organization.Phone1)
@Html.EditorFor(m => m.Organization.Phone1)
<p class="help-block">
@ViewData.ModelMetadata.Properties
.Where(m => m.PropertyName == "DayCount").FirstOrDefault().Description
</p>
</div>
I was about to use the accepted answer, but it didn't work for ASP.NET Core 1/2 (a.k.a. MVC 6) because ModelMetadata.FromLambdaExpression
no longer exists and has been moved to ExpressionMetadataProvider
(also usage has been changed slightly).
This is an updated extension method you can use with ASP.NET Core 1.1 & 2:
using System;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
public static class HtmlExtensions
{
public static IHtmlContent DescriptionFor<TModel, TValue>(this IHtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
if (html == null) throw new ArgumentNullException(nameof(html));
if (expression == null) throw new ArgumentNullException(nameof(expression));
var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider);
if (modelExplorer == null) throw new InvalidOperationException($"Failed to get model explorer for {ExpressionHelper.GetExpressionText(expression)}");
return new HtmlString(modelExplorer.Metadata.Description);
}
}
ASP.NET Core 1
For ASP.NET Core 1, the same code works, but you'll need different namespace usings
:
using System;
using System.Linq.Expressions;
using Microsoft.AspNet.Html.Abstractions;
using Microsoft.AspNet.Mvc.ViewFeatures;
Usage
@Html.DescriptionFor(model => model.Phone1)
You would have to write a custom helper that would reflect on your model to give the Description attribute value.
var attrib = (DisplayAttribute)Attribute.GetCustomAttribute(
member, typeof(DisplayAttribute));
var desc = attrib == null ? "" : attrib.GetDescription()
In addition to Jakob Gade'a great answer:
If you need to Support a DescriptionAttribute
instead of a DisplayAttribute
, his great solution still works if we override the MetadataProvider:
public class ExtendedModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<System.Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
//Possible Multiple Enumerations on IEnumerable fix
var attributeList = attributes as IList<System.Attribute> ?? attributes.ToList();
//Default behavior
var data = base.CreateMetadata(attributeList, containerType, modelAccessor, modelType, propertyName);
//Bind DescriptionAttribute
var description = attributeList.SingleOrDefault(a => typeof(DescriptionAttribute) == a.GetType());
if (description != null)
{
data.Description = ((DescriptionAttribute)description).Description;
}
return data;
}
}
This need to be registeres in the Application_Start
Method in Global.asax.cs
:
ModelMetadataProviders.Current = new ExtendedModelMetadataProvider();
If anyone is wondering how to use the accepted answer
1- In your solution explorer > Add new folder > name it"Helpers" for example
2- Add a new class, name it "CustomHtmlHelpers" for example
3- Paste the code :
public static class MvcHtmlHelpers
{
public static string DescriptionFor<TModel, TValue>(this HtmlHelper<TModel> self, Expression<Func<TModel, TValue>> expression)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, self.ViewData);
var description = metadata.Description;
return string.IsNullOrWhiteSpace(description) ? "" : description;
}
}
4- In your model or viewModel using it this:
[Display(Name = "User Name", Description = "Enter your User Name")]
public string FullName { get; set; }
5- In your Razor view, after the @model, type this line
@using YOUR_PROJECT.Helpers
6- Display the description like this:
@Html.DescriptionFor(m => m.FullName)
7- You may want to use the description to display text in the input placeholder:
@Html.DisplayNameFor(m => m.FullName)
@Html.TextBoxFor(m => m.FullName, new { @class = "form-control", placeholder = Html.DescriptionFor(m => m.FullName) })
Thanks