Changes to support DisplayColumn attribute. Updating the MvcSample as well to start using DisplayColumn attribute. Adding UnitTests for the same.
This commit is contained in:
parent
7396f58d99
commit
28516a0ae9
|
|
@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations;
|
|||
|
||||
namespace MvcSample.Web.Models
|
||||
{
|
||||
[DisplayColumn("Name")]
|
||||
public class User
|
||||
{
|
||||
public User()
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
<p><a href="http://asp.net" class="btn btn-primary btn-large">Learn more »</a></p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h3 title="@Model.Name" class="@nullValue">Hello @Model.Name! Happy @Model.Age birthday.</h3>
|
||||
<h3 title="@Model.Name" class="@nullValue">Hello @Html.DisplayTextFor(User => User)! Happy @Model.Age birthday.</h3>
|
||||
<h3 id="qux">This value was retrieved asynchronously: @(await AsyncValueRetrieval())</h3>
|
||||
<h3>Partial Async: @await Html.PartialAsync("HelloWorldPartial", Model)</h3>
|
||||
<h3>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
Display = attributes.OfType<DisplayAttribute>().FirstOrDefault();
|
||||
DisplayFormat = attributes.OfType<DisplayFormatAttribute>().FirstOrDefault();
|
||||
DisplayColumn = attributes.OfType<DisplayColumnAttribute>().FirstOrDefault();
|
||||
Editable = attributes.OfType<EditableAttribute>().FirstOrDefault();
|
||||
Required = attributes.OfType<RequiredAttribute>().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; }
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -378,6 +378,44 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
return string.Format(CultureInfo.CurrentCulture, GetString("ValueProviderResult_NoConverterExists"), p0, p1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// {0} has a DisplayColumn attribute for {1}, but property {1} does not exist..
|
||||
/// </summary>
|
||||
internal static string DataAnnotationsModelMetadataProvider_UnknownProperty
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetString("DataAnnotationsModelMetadataProvider_UnknownProperty");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// {0} has a DisplayColumn attribute for {1}, but property {1} does not exist..
|
||||
/// </summary>
|
||||
internal static string FormatDataAnnotationsModelMetadataProvider_UnknownProperty(object p0, object p1)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("DataAnnotationsModelMetadataProvider_UnknownProperty"), p0, p1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// {0} has a DisplayColumn attribute for {1}, but property {1} does not have a public 'get' method..
|
||||
/// </summary>
|
||||
internal static string DataAnnotationsModelMetadataProvider_UnreadableProperty
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetString("DataAnnotationsModelMetadataProvider_UnreadableProperty");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// {0} has a DisplayColumn attribute for {1}, but property {1} does not have a public 'get' method..
|
||||
/// </summary>
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -186,4 +186,10 @@
|
|||
<data name="ValueProviderResult_NoConverterExists" xml:space="preserve">
|
||||
<value>The parameter conversion from type '{0}' to type '{1}' failed because no type converter can convert between these types.</value>
|
||||
</data>
|
||||
<data name="DataAnnotationsModelMetadataProvider_UnknownProperty" xml:space="preserve">
|
||||
<value>{0} has a DisplayColumn attribute for {1}, but property {1} does not exist.</value>
|
||||
</data>
|
||||
<data name="DataAnnotationsModelMetadataProvider_UnreadableProperty" xml:space="preserve">
|
||||
<value>{0} has a DisplayColumn attribute for {1}, but property {1} does not have a public 'get' method.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -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<object[]> SimpleDisplayTextData
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new object[]
|
||||
{
|
||||
new Func<object>(() => new ComplexClass()
|
||||
{
|
||||
Prop1 = new Class1 { Prop1 = "Hello" }
|
||||
}),
|
||||
typeof(ComplexClass),
|
||||
"Class1"
|
||||
};
|
||||
yield return new object[]
|
||||
{
|
||||
new Func<object>(() => new Class1()),
|
||||
typeof(Class1),
|
||||
"Class1"
|
||||
};
|
||||
yield return new object[]
|
||||
{
|
||||
new Func<object>(() => new ClassWithNoProperties()),
|
||||
typeof(ClassWithNoProperties),
|
||||
string.Empty
|
||||
};
|
||||
yield return new object[]
|
||||
{
|
||||
null,
|
||||
typeof(object),
|
||||
null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData("SimpleDisplayTextData")]
|
||||
public void TestSimpleDisplayText(Func<object> modelAccessor, Type modelType, string expectedResult)
|
||||
{
|
||||
// Arrange
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = new ModelMetadata(provider, null, modelAccessor, modelType, null);
|
||||
|
||||
// Act
|
||||
var result = metadata.SimpleDisplayText;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedResult, result);
|
||||
}
|
||||
|
||||
private class ClassWithNoProperties
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private class ComplexClass
|
||||
{
|
||||
public Class1 Prop1 { get; set; }
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue