Calculate `ModelMetadata.DataTypeName` based on metadata
- helps MVC helpers like `@Html.EditorFor()` select the correct template - #933 nit: add XML doc for `DataTypeName` in base `ModelMetadata`
This commit is contained in:
parent
12477c9f52
commit
a5600a74a3
|
|
@ -12,6 +12,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
// is correct.
|
||||
public class CachedDataAnnotationsModelMetadata : CachedModelMetadata<CachedDataAnnotationsMetadataAttributes>
|
||||
{
|
||||
private static readonly string HtmlName = DataType.Html.ToString();
|
||||
private bool _isEditFormatStringFromCache;
|
||||
|
||||
public CachedDataAnnotationsModelMetadata(CachedDataAnnotationsModelMetadata prototype,
|
||||
|
|
@ -47,6 +48,31 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
: base.ComputeNullDisplayText();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate <see cref="ModelMetadata.DataTypeName"/> based on presence of a <see cref="DataTypeAttribute"/>
|
||||
/// and its <see cref="DataTypeAttribute.GetDataTypeName()"/> method.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Calculated <see cref="ModelMetadata.DataTypeName"/> value.
|
||||
/// <see cref="DataTypeAttribute.GetDataTypeName()"/> value if a <see cref="DataTypeAttribute"/> exists.
|
||||
/// <c>"Html"</c> if a <see cref="DisplayFormatAttribute"/> exists with its
|
||||
/// <see cref="DisplayFormatAttribute.HtmlEncode"/> value <c>false</c>. <c>null</c> otherwise.
|
||||
/// </returns>
|
||||
protected override string ComputeDataTypeName()
|
||||
{
|
||||
if (PrototypeCache.DataType != null)
|
||||
{
|
||||
return PrototypeCache.DataType.GetDataTypeName();
|
||||
}
|
||||
|
||||
if (PrototypeCache.DisplayFormat != null && !PrototypeCache.DisplayFormat.HtmlEncode)
|
||||
{
|
||||
return HtmlName;
|
||||
}
|
||||
|
||||
return base.ComputeDataTypeName();
|
||||
}
|
||||
|
||||
protected override string ComputeDescription()
|
||||
{
|
||||
return PrototypeCache.Display != null
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
private bool _convertEmptyStringToNull;
|
||||
private string _nullDisplayText;
|
||||
private string _dataTypeName;
|
||||
private string _description;
|
||||
private string _displayFormatString;
|
||||
private string _displayName;
|
||||
|
|
@ -31,6 +32,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
|
||||
private bool _convertEmptyStringToNullComputed;
|
||||
private bool _nullDisplayTextComputed;
|
||||
private bool _dataTypeNameComputed;
|
||||
private bool _descriptionComputed;
|
||||
private bool _displayFormatStringComputed;
|
||||
private bool _displayNameComputed;
|
||||
|
|
@ -105,6 +107,27 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override string DataTypeName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_dataTypeNameComputed)
|
||||
{
|
||||
_dataTypeName = ComputeDataTypeName();
|
||||
_dataTypeNameComputed = true;
|
||||
}
|
||||
|
||||
return _dataTypeName;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_dataTypeName = value;
|
||||
_dataTypeNameComputed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override string Description
|
||||
{
|
||||
get
|
||||
|
|
@ -338,6 +361,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
return base.NullDisplayText;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the <see cref="DataTypeName"/> value.
|
||||
/// </summary>
|
||||
/// <returns>Calculated <see cref="DataTypeName"/> value.</returns>
|
||||
protected virtual string ComputeDataTypeName()
|
||||
{
|
||||
return base.DataTypeName;
|
||||
}
|
||||
|
||||
protected virtual string ComputeDescription()
|
||||
{
|
||||
return base.Description;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
set { _convertEmptyStringToNull = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the <see cref="Model"/>'s datatype. Overrides <see cref="ModelType"/> in some
|
||||
/// display scenarios.
|
||||
/// </summary>
|
||||
/// <value><c>null</c> unless set manually or through additional metadata e.g. attributes.</value>
|
||||
public virtual string DataTypeName { get; set; }
|
||||
|
||||
public virtual string Description { get; set; }
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
return new TheoryData<Attribute, Func<ModelMetadata, string>>
|
||||
{
|
||||
{
|
||||
new DataTypeAttribute("value"), metadata => metadata.DataTypeName
|
||||
},
|
||||
{
|
||||
new DataTypeWithCustomDisplayFormat(), metadata => metadata.DisplayFormatString
|
||||
},
|
||||
|
|
@ -207,6 +210,69 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
Assert.Equal(expectedResult, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DataTypeName_Null_IfHtmlEncodeTrue()
|
||||
{
|
||||
// Arrange
|
||||
var displayFormat = new DisplayFormatAttribute { HtmlEncode = true, };
|
||||
var provider = new DataAnnotationsModelMetadataProvider();
|
||||
var metadata = new CachedDataAnnotationsModelMetadata(
|
||||
provider,
|
||||
containerType: null,
|
||||
modelType: typeof(object),
|
||||
propertyName: null,
|
||||
attributes: new Attribute[] { displayFormat });
|
||||
|
||||
// Act
|
||||
var result = metadata.DataTypeName;
|
||||
|
||||
// Assert
|
||||
Assert.Null(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DataTypeName_Html_IfHtmlEncodeFalse()
|
||||
{
|
||||
// Arrange
|
||||
var expected = "Html";
|
||||
var displayFormat = new DisplayFormatAttribute { HtmlEncode = false, };
|
||||
var provider = new DataAnnotationsModelMetadataProvider();
|
||||
var metadata = new CachedDataAnnotationsModelMetadata(
|
||||
provider,
|
||||
containerType: null,
|
||||
modelType: typeof(object),
|
||||
propertyName: null,
|
||||
attributes: new Attribute[] { displayFormat });
|
||||
|
||||
// Act
|
||||
var result = metadata.DataTypeName;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DataTypeName_AttributesHaveExpectedPrecedence()
|
||||
{
|
||||
// Arrange
|
||||
var expected = "MultilineText";
|
||||
var dataType = new DataTypeAttribute(DataType.MultilineText);
|
||||
var displayFormat = new DisplayFormatAttribute { HtmlEncode = false, };
|
||||
var provider = new DataAnnotationsModelMetadataProvider();
|
||||
var metadata = new CachedDataAnnotationsModelMetadata(
|
||||
provider,
|
||||
containerType: null,
|
||||
modelType: typeof(object),
|
||||
propertyName: null,
|
||||
attributes: new Attribute[] { dataType, displayFormat });
|
||||
|
||||
// Act
|
||||
var result = metadata.DataTypeName;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DisplayFormatString_AttributesHaveExpectedPrecedence()
|
||||
{
|
||||
|
|
@ -220,7 +286,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
containerType: null,
|
||||
modelType: typeof(object),
|
||||
propertyName: null,
|
||||
attributes: new Attribute[] { dataType, displayFormat, });
|
||||
attributes: new Attribute[] { dataType, displayFormat });
|
||||
|
||||
// Act
|
||||
var result = metadata.DisplayFormatString;
|
||||
|
|
@ -246,7 +312,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
containerType: null,
|
||||
modelType: typeof(object),
|
||||
propertyName: null,
|
||||
attributes: new Attribute[] { dataType, displayFormat, });
|
||||
attributes: new Attribute[] { dataType, displayFormat });
|
||||
|
||||
// Act
|
||||
var result = metadata.EditFormatString;
|
||||
|
|
|
|||
Loading…
Reference in New Issue