diff --git a/samples/MvcSample.Web/Models/User.cs b/samples/MvcSample.Web/Models/User.cs
index 910d7ec676..ed0203abb5 100644
--- a/samples/MvcSample.Web/Models/User.cs
+++ b/samples/MvcSample.Web/Models/User.cs
@@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations;
namespace MvcSample.Web.Models
{
+ [DisplayColumn("Name")]
public class User
{
public User()
diff --git a/samples/MvcSample.Web/Views/Shared/MyView.cshtml b/samples/MvcSample.Web/Views/Shared/MyView.cshtml
index 18ae092b23..c8d8ebb613 100644
--- a/samples/MvcSample.Web/Views/Shared/MyView.cshtml
+++ b/samples/MvcSample.Web/Views/Shared/MyView.cshtml
@@ -54,7 +54,7 @@
Learn more »
-
Hello @Model.Name! Happy @Model.Age birthday.
+ Hello @Html.DisplayTextFor(User => User)! Happy @Model.Age birthday.
This value was retrieved asynchronously: @(await AsyncValueRetrieval())
Partial Async: @await Html.PartialAsync("HelloWorldPartial", Model)
diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/CachedDataAnnotationsMetadataAttributes.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/CachedDataAnnotationsMetadataAttributes.cs
index 4bcd69a49d..b01fce52e1 100644
--- a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/CachedDataAnnotationsMetadataAttributes.cs
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/CachedDataAnnotationsMetadataAttributes.cs
@@ -14,6 +14,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
Display = attributes.OfType().FirstOrDefault();
DisplayFormat = attributes.OfType().FirstOrDefault();
+ DisplayColumn = attributes.OfType().FirstOrDefault();
Editable = attributes.OfType().FirstOrDefault();
Required = attributes.OfType().FirstOrDefault();
}
@@ -22,6 +23,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public DisplayFormatAttribute DisplayFormat { get; protected set; }
+ public DisplayColumnAttribute DisplayColumn { get; protected set; }
+
public EditableAttribute Editable { get; protected set; }
public RequiredAttribute Required { get; protected set; }
diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/CachedDataAnnotationsModelMetadata.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/CachedDataAnnotationsModelMetadata.cs
index 43d547c1a8..145813943e 100644
--- a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/CachedDataAnnotationsModelMetadata.cs
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/CachedDataAnnotationsModelMetadata.cs
@@ -3,6 +3,8 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Reflection;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
@@ -63,6 +65,26 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return (PrototypeCache.Required != null) || base.ComputeIsRequired();
}
+ protected override string ComputeSimpleDisplayText()
+ {
+ if (Model != null &&
+ PrototypeCache.DisplayColumn != null &&
+ !string.IsNullOrEmpty(PrototypeCache.DisplayColumn.DisplayColumn))
+ {
+ var displayColumnProperty = ModelType.GetTypeInfo().GetDeclaredProperty(
+ PrototypeCache.DisplayColumn.DisplayColumn);
+ ValidateDisplayColumnAttribute(PrototypeCache.DisplayColumn, displayColumnProperty, ModelType);
+
+ var simpleDisplayTextValue = displayColumnProperty.GetValue(Model, null);
+ if (simpleDisplayTextValue != null)
+ {
+ return simpleDisplayTextValue.ToString();
+ }
+ }
+
+ return base.ComputeSimpleDisplayText();
+ }
+
public override string GetDisplayName()
{
// DisplayAttribute doesn't require you to set a name, so this could be null.
@@ -78,5 +100,23 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// If DisplayAttribute does not specify a name, we'll fall back to the property name.
return base.GetDisplayName();
}
+
+ private static void ValidateDisplayColumnAttribute(DisplayColumnAttribute displayColumnAttribute,
+ PropertyInfo displayColumnProperty, Type modelType)
+ {
+ if (displayColumnProperty == null)
+ {
+ throw new InvalidOperationException(
+ Resources.FormatDataAnnotationsModelMetadataProvider_UnknownProperty(
+ modelType.FullName, displayColumnAttribute.DisplayColumn));
+ }
+
+ if (displayColumnProperty.GetGetMethod() == null)
+ {
+ throw new InvalidOperationException(
+ Resources.FormatDataAnnotationsModelMetadataProvider_UnreadableProperty(
+ modelType.FullName, displayColumnAttribute.DisplayColumn));
+ }
+ }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Properties/Resources.Designer.cs
index 73930c3294..a11ddafcda 100644
--- a/src/Microsoft.AspNet.Mvc.ModelBinding/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Properties/Resources.Designer.cs
@@ -378,6 +378,44 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return string.Format(CultureInfo.CurrentCulture, GetString("ValueProviderResult_NoConverterExists"), p0, p1);
}
+ ///
+ /// {0} has a DisplayColumn attribute for {1}, but property {1} does not exist..
+ ///
+ internal static string DataAnnotationsModelMetadataProvider_UnknownProperty
+ {
+ get
+ {
+ return GetString("DataAnnotationsModelMetadataProvider_UnknownProperty");
+ }
+ }
+
+ ///
+ /// {0} has a DisplayColumn attribute for {1}, but property {1} does not exist..
+ ///
+ internal static string FormatDataAnnotationsModelMetadataProvider_UnknownProperty(object p0, object p1)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("DataAnnotationsModelMetadataProvider_UnknownProperty"), p0, p1);
+ }
+
+ ///
+ /// {0} has a DisplayColumn attribute for {1}, but property {1} does not have a public 'get' method..
+ ///
+ internal static string DataAnnotationsModelMetadataProvider_UnreadableProperty
+ {
+ get
+ {
+ return GetString("DataAnnotationsModelMetadataProvider_UnreadableProperty");
+ }
+ }
+
+ ///
+ /// {0} has a DisplayColumn attribute for {1}, but property {1} does not have a public 'get' method..
+ ///
+ internal static string FormatDataAnnotationsModelMetadataProvider_UnreadableProperty(object p0, object p1)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("DataAnnotationsModelMetadataProvider_UnreadableProperty"), p0, p1);
+ }
+
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Resources.resx b/src/Microsoft.AspNet.Mvc.ModelBinding/Resources.resx
index 22d1017224..5bde6c1dbe 100644
--- a/src/Microsoft.AspNet.Mvc.ModelBinding/Resources.resx
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Resources.resx
@@ -186,4 +186,10 @@
The parameter conversion from type '{0}' to type '{1}' failed because no type converter can convert between these types.
+
+ {0} has a DisplayColumn attribute for {1}, but property {1} does not exist.
+
+
+ {0} has a DisplayColumn attribute for {1}, but property {1} does not have a public 'get' method.
+
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataTest.cs
index dcdf510b11..5d51a73881 100644
--- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataTest.cs
+++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataTest.cs
@@ -182,6 +182,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
private class Class1
{
public string Prop1 { get; set; }
+ public override string ToString()
+ {
+ return "Class1";
+ }
}
private class Class2
@@ -220,6 +224,69 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
Assert.Equal("Object", result);
}
#endif
+ // SimpleDisplayText
+
+ public static IEnumerable