Add `ModelMetadata.HasNonDefaultEditFormat` property
- add `DataType` property to `CachedDataAnnotationsMetadataAttributes` in support of `ComputeHasNonDefaultEditFormat()` - provide doc comments and flesh out the implementation of `DisplayFormatString` and `EditFormatString` nits: - add comment about _not_ overriding `ComputeIsComplexType()` in `CachedDataAnnotationsModelMetadata` - restore alphabetic order in `CachedDataAnnotationsMetadataAttributes` - seal `SimpleDisplayText` in `CachedModelMetadata<TPrototypeCache>`, matching MVC 5.2
This commit is contained in:
parent
a3ab95713e
commit
4351ddd092
|
|
@ -12,21 +12,44 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
public CachedDataAnnotationsMetadataAttributes(IEnumerable<Attribute> attributes)
|
||||
{
|
||||
DataType = attributes.OfType<DataTypeAttribute>().FirstOrDefault();
|
||||
Display = attributes.OfType<DisplayAttribute>().FirstOrDefault();
|
||||
DisplayFormat = attributes.OfType<DisplayFormatAttribute>().FirstOrDefault();
|
||||
DisplayColumn = attributes.OfType<DisplayColumnAttribute>().FirstOrDefault();
|
||||
DisplayFormat = attributes.OfType<DisplayFormatAttribute>().FirstOrDefault();
|
||||
Editable = attributes.OfType<EditableAttribute>().FirstOrDefault();
|
||||
HiddenInput = attributes.OfType<HiddenInputAttribute>().FirstOrDefault();
|
||||
Required = attributes.OfType<RequiredAttribute>().FirstOrDefault();
|
||||
ScaffoldColumn = attributes.OfType<ScaffoldColumnAttribute>().FirstOrDefault();
|
||||
|
||||
// Special case the [DisplayFormat] attribute hanging off an applied [DataType] attribute. This property is
|
||||
// non-null for DataType.Currency, DataType.Date, DataType.Time, and potentially custom [DataType]
|
||||
// subclasses. The DataType.Currency, DataType.Date, and DataType.Time [DisplayFormat] attributes have a
|
||||
// non-null DataFormatString and the DataType.Date and DataType.Time [DisplayFormat] attributes have
|
||||
// ApplyFormatInEditMode==true.
|
||||
if (DisplayFormat == null && DataType != null)
|
||||
{
|
||||
DisplayFormat = DataType.DisplayFormat;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (or sets in subclasses) <see cref="DataTypeAttribute"/> found in collection passed to the
|
||||
/// <see cref="CachedDataAnnotationsMetadataAttributes(IEnumerable{Attribute})"/> constructor, if any.
|
||||
/// </summary>
|
||||
public DataTypeAttribute DataType { get; protected set; }
|
||||
|
||||
public DisplayAttribute Display { get; protected set; }
|
||||
|
||||
public DisplayFormatAttribute DisplayFormat { get; protected set; }
|
||||
|
||||
public DisplayColumnAttribute DisplayColumn { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets (or sets in subclasses) <see cref="DisplayFormatAttribute"/> found in collection passed to the
|
||||
/// <see cref="CachedDataAnnotationsMetadataAttributes(IEnumerable{Attribute})"/> constructor, if any.
|
||||
/// If no such attribute was found but a <see cref="DataTypeAttribute"/> was, gets the
|
||||
/// <see cref="DataTypeAttribute.DisplayFormat"/> value.
|
||||
/// </summary>
|
||||
public DisplayFormatAttribute DisplayFormat { get; protected set; }
|
||||
|
||||
public EditableAttribute Editable { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,12 @@ using System.Reflection;
|
|||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
// Class does not override ComputeIsComplexType() because value calculated in ModelMetadata's base implementation
|
||||
// is correct.
|
||||
public class CachedDataAnnotationsModelMetadata : CachedModelMetadata<CachedDataAnnotationsMetadataAttributes>
|
||||
{
|
||||
private bool _isEditFormatStringFromCache;
|
||||
|
||||
public CachedDataAnnotationsModelMetadata(CachedDataAnnotationsModelMetadata prototype,
|
||||
Func<object> modelAccessor)
|
||||
: base(prototype, modelAccessor)
|
||||
|
|
@ -50,6 +54,22 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
: base.ComputeDescription();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate <see cref="ModelMetadata.DisplayFormatString"/> based on presence of an
|
||||
/// <see cref="DisplayFormatAttribute"/> and its <see cref="DisplayFormatAttribute.DataFormatString"/> value.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Calculated <see cref="ModelMetadata.DisplayFormatString"/> value.
|
||||
/// <see cref="DisplayFormatAttribute.DataFormatString"/> if an <see cref="DisplayFormatAttribute"/> exists.
|
||||
/// <c>null</c> otherwise.
|
||||
/// </returns>
|
||||
protected override string ComputeDisplayFormatString()
|
||||
{
|
||||
return PrototypeCache.DisplayFormat != null
|
||||
? PrototypeCache.DisplayFormat.DataFormatString
|
||||
: base.ComputeEditFormatString();
|
||||
}
|
||||
|
||||
protected override string ComputeDisplayName()
|
||||
{
|
||||
// DisplayName may be provided by DisplayAttribute.
|
||||
|
|
@ -67,6 +87,73 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
return base.ComputeDisplayName();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate <see cref="ModelMetadata.EditFormatString"/> based on presence of an
|
||||
/// <see cref="DisplayFormatAttribute"/> and its <see cref="DisplayFormatAttribute.ApplyFormatInEditMode"/> and
|
||||
/// <see cref="DisplayFormatAttribute.DataFormatString"/> values.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Calculated <see cref="ModelMetadata.DisplayFormatString"/> value.
|
||||
/// <see cref="DisplayFormatAttribute.DataFormatString"/> if an <see cref="DisplayFormatAttribute"/> exists and
|
||||
/// its <see cref="DisplayFormatAttribute.ApplyFormatInEditMode"/> is <c>true</c>; <c>null</c> otherwise.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Subclasses overriding this method should also override <see cref="ComputeHasNonDefaultEditFormat"/> to
|
||||
/// ensure the two calculations remain consistent.
|
||||
/// </remarks>
|
||||
protected override string ComputeEditFormatString()
|
||||
{
|
||||
if (PrototypeCache.DisplayFormat != null && PrototypeCache.DisplayFormat.ApplyFormatInEditMode)
|
||||
{
|
||||
_isEditFormatStringFromCache = true;
|
||||
return PrototypeCache.DisplayFormat.DataFormatString;
|
||||
}
|
||||
|
||||
return base.ComputeEditFormatString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate <see cref="ModelMetadata.HasNonDefaultEditFormat"/> based on
|
||||
/// <see cref="ModelMetadata.EditFormatString"/> and presence of <see cref="DataTypeAttribute"/> and
|
||||
/// <see cref="DisplayFormatAttribute"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Calculated <see cref="ModelMetadata.HasNonDefaultEditFormat"/> value. <c>true</c> if
|
||||
/// <see cref="ModelMetadata.EditFormatString"/> is non-<c>null</c>, non-empty, and came from the cache (was
|
||||
/// not set directly). In addition the applied <see cref="DisplayFormatAttribute"/> must not have come from an
|
||||
/// applied <see cref="DataTypeAttribute"/>. <c>false</c> otherwise.
|
||||
/// </returns>
|
||||
protected override bool ComputeHasNonDefaultEditFormat()
|
||||
{
|
||||
// Following calculation ignores possibility something (an IModelMetadataProvider) set EditFormatString
|
||||
// directly.
|
||||
if (!string.IsNullOrEmpty(EditFormatString) && _isEditFormatStringFromCache)
|
||||
{
|
||||
// Have a non-empty EditFormatString based on [DisplayFormat] from our cache.
|
||||
if (PrototypeCache.DataType == null)
|
||||
{
|
||||
// Attributes include no [DataType]; [DisplayFormat] was applied directly.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (PrototypeCache.DataType.DisplayFormat != PrototypeCache.DisplayFormat)
|
||||
{
|
||||
// Attributes include separate [DataType] and [DisplayFormat]; [DisplayFormat] provided override.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (PrototypeCache.DataType.GetType() != typeof(DataTypeAttribute))
|
||||
{
|
||||
// Attributes include [DisplayFormat] copied from [DataType] and [DataType] was of a subclass.
|
||||
// Assume the [DataType] constructor used the protected DisplayFormat setter to override its
|
||||
// default. That is derived [DataType] provided override.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return base.ComputeHasNonDefaultEditFormat();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate <see cref="ModelMetadata.HideSurroundingHtml"/> based on presence of an
|
||||
/// <see cref="HiddenInputAttribute"/> and its <see cref="HiddenInputAttribute.DisplayValue"/> value.
|
||||
|
|
|
|||
|
|
@ -18,7 +18,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
private bool _convertEmptyStringToNull;
|
||||
private string _nullDisplayText;
|
||||
private string _description;
|
||||
private string _displayFormatString;
|
||||
private string _displayName;
|
||||
private string _editFormatString;
|
||||
private bool _hasNonDefaultEditFormat;
|
||||
private bool _hideSurroundingHtml;
|
||||
private bool _isReadOnly;
|
||||
private bool _isComplexType;
|
||||
|
|
@ -29,7 +32,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
private bool _convertEmptyStringToNullComputed;
|
||||
private bool _nullDisplayTextComputed;
|
||||
private bool _descriptionComputed;
|
||||
private bool _displayFormatStringComputed;
|
||||
private bool _displayNameComputed;
|
||||
private bool _editFormatStringComputed;
|
||||
private bool _hasNonDefaultEditFormatComputed;
|
||||
private bool _hideSurroundingHtmlComputed;
|
||||
private bool _isReadOnlyComputed;
|
||||
private bool _isComplexTypeComputed;
|
||||
|
|
@ -117,6 +123,27 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override string DisplayFormatString
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_displayFormatStringComputed)
|
||||
{
|
||||
_displayFormatString = ComputeDisplayFormatString();
|
||||
_displayFormatStringComputed = true;
|
||||
}
|
||||
|
||||
return _displayFormatString;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_displayFormatString = value;
|
||||
_displayFormatStringComputed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override string DisplayName
|
||||
{
|
||||
get
|
||||
|
|
@ -136,6 +163,48 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override string EditFormatString
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_editFormatStringComputed)
|
||||
{
|
||||
_editFormatString = ComputeEditFormatString();
|
||||
_editFormatStringComputed = true;
|
||||
}
|
||||
|
||||
return _editFormatString;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_editFormatString = value;
|
||||
_editFormatStringComputed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override bool HasNonDefaultEditFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_hasNonDefaultEditFormatComputed)
|
||||
{
|
||||
_hasNonDefaultEditFormat = ComputeHasNonDefaultEditFormat();
|
||||
_hasNonDefaultEditFormatComputed = true;
|
||||
}
|
||||
|
||||
return _hasNonDefaultEditFormat;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_hasNonDefaultEditFormat = value;
|
||||
_hasNonDefaultEditFormatComputed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override bool HideSurroundingHtml
|
||||
{
|
||||
|
|
@ -242,6 +311,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override string SimpleDisplayText
|
||||
{
|
||||
get
|
||||
{
|
||||
// Value already cached in ModelMetadata. That class also already exposes ComputeSimpleDisplayText()
|
||||
// for overrides. Sealed here for consistency with other properties.
|
||||
return base.SimpleDisplayText;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.SimpleDisplayText = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected TPrototypeCache PrototypeCache { get; set; }
|
||||
|
||||
protected virtual bool ComputeConvertEmptyStringToNull()
|
||||
|
|
@ -259,11 +343,38 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
return base.Description;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the <see cref="DisplayFormatString"/> value.
|
||||
/// </summary>
|
||||
/// <returns>Calculated <see cref="DisplayFormatString"/> value.</returns>
|
||||
protected virtual string ComputeDisplayFormatString()
|
||||
{
|
||||
return base.DisplayFormatString;
|
||||
}
|
||||
|
||||
protected virtual string ComputeDisplayName()
|
||||
{
|
||||
return base.DisplayName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the <see cref="EditFormatString"/> value.
|
||||
/// </summary>
|
||||
/// <returns>Calculated <see cref="EditFormatString"/> value.</returns>
|
||||
protected virtual string ComputeEditFormatString()
|
||||
{
|
||||
return base.EditFormatString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the <see cref="HasNonDefaultEditFormat"/> value.
|
||||
/// </summary>
|
||||
/// <returns>Calculated <see cref="HasNonDefaultEditFormat"/> value.</returns>
|
||||
protected virtual bool ComputeHasNonDefaultEditFormat()
|
||||
{
|
||||
return base.HasNonDefaultEditFormat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the <see cref="HideSurroundingHtml"/> value.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
||||
|
|
@ -64,12 +63,30 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
|
||||
public virtual string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the composite format <see cref="string"/> (see
|
||||
/// http://msdn.microsoft.com/en-us/library/txafckwd.aspx) used to display the <see cref="Model"/>.
|
||||
/// </summary>
|
||||
public virtual string DisplayFormatString { get; set; }
|
||||
|
||||
public virtual string DisplayName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the composite format <see cref="string"/> (see
|
||||
/// http://msdn.microsoft.com/en-us/library/txafckwd.aspx) used to edit the <see cref="Model"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see cref="IModelMetadataProvider"/> instances that set this property to a non-<c>null</c>, non-empty,
|
||||
/// non-default value should also set <see cref="HasNonDefaultEditFormat"/> to <c>true</c>.
|
||||
/// </remarks>
|
||||
public virtual string EditFormatString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether <see cref="EditFormatString"/> has a non-<c>null</c>, non-empty
|
||||
/// value different from the default for the datatype.
|
||||
/// </summary>
|
||||
public virtual bool HasNonDefaultEditFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the "HiddenInput" display template should return
|
||||
/// <c>string.Empty</c> (not the expression value) and whether the "HiddenInput" editor template should not
|
||||
|
|
|
|||
Loading…
Reference in New Issue