Introducing DisplayText, DisplayTextFor, Id, IdFor, IdForModel.
Fixing CachedDataAnnotationsModelMetadata to support NullDisplayText.
This commit is contained in:
parent
112a5ddc50
commit
d63d998e95
|
|
@ -96,7 +96,8 @@ namespace MvcSample.Web
|
||||||
Address = "Dependents address",
|
Address = "Dependents address",
|
||||||
Alive = false,
|
Alive = false,
|
||||||
},
|
},
|
||||||
About = "I am a Software Engineer"
|
Profession = "Software Engineer",
|
||||||
|
About = "I like playing Football"
|
||||||
};
|
};
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ namespace MvcSample.Web.Models
|
||||||
public User Dependent { get; set; }
|
public User Dependent { get; set; }
|
||||||
public bool Alive { get; set; }
|
public bool Alive { get; set; }
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
[DisplayFormat(ConvertEmptyStringToNull = true, NullDisplayText = "You can explain about your profession")]
|
||||||
|
public string Profession { get; set; }
|
||||||
public string About { get; set; }
|
public string About { get; set; }
|
||||||
public string Log { get; set; }
|
public string Log { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<h4 title="@Model.Name" class="@ViewBag.NullValue">Hello @Model.Name! Happy @(Model.Age)th birthday.</h4>
|
<h4 title="@Model.Name" class="@ViewBag.NullValue">Hello @Html.DisplayTextFor(model => model.Name)! Happy @(Model.Age)th birthday.</h4>
|
||||||
}
|
}
|
||||||
|
|
||||||
@{
|
@{
|
||||||
|
|
@ -69,10 +69,18 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label class="control-label col-md-2">Model.Name</label>
|
<label class="control-label col-md-2">Model.Profession</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@Html.TextArea("About", "You can explain about your profession, hobbies etc.", 5, 40, htmlAttributes: new { style = "font-weight:bold" })
|
<input type="text" id="@Html.IdFor(model => model.Profession)" name="Profession" value='@Html.DisplayText("Profession")' />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<label class="control-label col-md-2">Model.About</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@Html.TextArea("About", "You can explain about your hobbies, work etc.", 5, 40, htmlAttributes: new { style = "font-weight:bold" })
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
return GenerateDisplayName(metadata, expression);
|
return GenerateDisplayName(metadata, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public HtmlString DisplayText(string name)
|
||||||
|
{
|
||||||
|
var metadata = ExpressionMetadataProvider.FromStringExpression(name, ViewData, MetadataProvider);
|
||||||
|
|
||||||
|
return GenerateDisplayText(metadata);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public HtmlString DropDownList(string name, IEnumerable<SelectListItem> selectList, string optionLabel,
|
public HtmlString DropDownList(string name, IEnumerable<SelectListItem> selectList, string optionLabel,
|
||||||
|
|
@ -291,6 +298,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
htmlAttributes: htmlAttributes);
|
htmlAttributes: htmlAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public HtmlString Id(string name)
|
||||||
|
{
|
||||||
|
return GenerateId(name);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public HtmlString Label(string expression, string labelText, object htmlAttributes)
|
public HtmlString Label(string expression, string labelText, object htmlAttributes)
|
||||||
{
|
{
|
||||||
|
|
@ -652,6 +665,11 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
|
|
||||||
return new HtmlString(Encode(resolvedDisplayName));
|
return new HtmlString(Encode(resolvedDisplayName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual HtmlString GenerateDisplayText(ModelMetadata metadata)
|
||||||
|
{
|
||||||
|
return new HtmlString(metadata.SimpleDisplayText);
|
||||||
|
}
|
||||||
|
|
||||||
protected HtmlString GenerateDropDown(ModelMetadata metadata, string expression,
|
protected HtmlString GenerateDropDown(ModelMetadata metadata, string expression,
|
||||||
IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes)
|
IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes)
|
||||||
|
|
@ -760,6 +778,11 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
htmlAttributes: htmlAttributeDictionary);
|
htmlAttributes: htmlAttributeDictionary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual HtmlString GenerateId(string expression)
|
||||||
|
{
|
||||||
|
return new HtmlString(Encode(ViewData.TemplateInfo.GetFullHtmlFieldName(expression)));
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual HtmlString GenerateLabel([NotNull] ModelMetadata metadata,
|
protected virtual HtmlString GenerateLabel([NotNull] ModelMetadata metadata,
|
||||||
string htmlFieldName,
|
string htmlFieldName,
|
||||||
string labelText,
|
string labelText,
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
|
|
||||||
return GenerateDisplayName(metadata, expressionText);
|
return GenerateDisplayName(metadata, expressionText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public HtmlString DisplayTextFor<TValue>([NotNull] Expression<Func<TModel, TValue>> expression)
|
||||||
|
{
|
||||||
|
return GenerateDisplayText(GetModelMetadata(expression));
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public HtmlString EditorFor<TValue>(
|
public HtmlString EditorFor<TValue>(
|
||||||
|
|
@ -134,6 +140,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
htmlAttributes: htmlAttributes);
|
htmlAttributes: htmlAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public HtmlString IdFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression)
|
||||||
|
{
|
||||||
|
return GenerateId(GetExpressionName(expression));
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public HtmlString LabelFor<TValue>([NotNull] Expression<Func<TModel, TValue>> expression, string labelText, object htmlAttributes)
|
public HtmlString LabelFor<TValue>([NotNull] Expression<Func<TModel, TValue>> expression, string labelText, object htmlAttributes)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,15 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
{
|
{
|
||||||
return htmlHelper.Name(string.Empty);
|
return htmlHelper.Name(string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the full HTML field id for the current model.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="htmlHelper">The <see cref="HtmlHelper"/> instance that this method extends.</param>
|
||||||
|
/// <returns>An <see cref="HtmlString"/> that represents HTML markup.</returns>
|
||||||
|
public static HtmlString IdForModel([NotNull] this IHtmlHelper htmlHelper)
|
||||||
|
{
|
||||||
|
return htmlHelper.Id(string.Empty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,16 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
/// </returns>
|
/// </returns>
|
||||||
HtmlString DisplayName(string expression);
|
HtmlString DisplayName(string expression);
|
||||||
|
|
||||||
|
/// Returns the HtmlString corresponding to the property in the model specified by the name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">
|
||||||
|
/// The string which identifies the object for which the HtmlString should be returned.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// New <see cref="HtmlString"/> containing the display text. If the value is null,
|
||||||
|
/// then it returns the ModelMetadata.NullDisplayText.
|
||||||
|
/// </returns>
|
||||||
|
HtmlString DisplayText(string name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a single-selection HTML {select} element using the specified name of the form field,
|
/// Returns a single-selection HTML {select} element using the specified name of the form field,
|
||||||
/// list items, option label, and HTML attributes.
|
/// list items, option label, and HTML attributes.
|
||||||
|
|
@ -248,6 +258,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
|
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
|
||||||
HtmlString Hidden(string name, object value, object htmlAttributes);
|
HtmlString Hidden(string name, object value, object htmlAttributes);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Id of the given string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The string which identifies the object for which the Id should be returned.</param>
|
||||||
|
/// <returns>New <see cref="HtmlString"/> containing the Id.</returns>
|
||||||
|
HtmlString Id(string name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns an HTML label element and the property name of the property that is represented by the specified
|
/// Returns an HTML label element and the property name of the property that is represented by the specified
|
||||||
/// expression.
|
/// expression.
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,18 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
HtmlString DisplayNameForInnerType<TInnerModel, TValue>(
|
HtmlString DisplayNameForInnerType<TInnerModel, TValue>(
|
||||||
[NotNull] Expression<Func<TInnerModel, TValue>> expression);
|
[NotNull] Expression<Func<TInnerModel, TValue>> expression);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the HtmlString corresponding to the expression specified.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="expression">
|
||||||
|
/// The expression identifies the object for which the HtmlString should be returned.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// New <see cref="HtmlString"/> containing the display text. If the value is null,
|
||||||
|
/// then it returns the ModelMetadata.NullDisplayText.
|
||||||
|
/// </returns>
|
||||||
|
HtmlString DisplayTextFor<TValue>([NotNull] Expression<Func<TModel, TValue>> expression);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a single-selection HTML {select} element for the object that is represented
|
/// Returns a single-selection HTML {select} element for the object that is represented
|
||||||
/// by the specified expression using the specified list items, option label, and HTML attributes.
|
/// by the specified expression using the specified list items, option label, and HTML attributes.
|
||||||
|
|
@ -125,6 +137,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
HtmlString HiddenFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression,
|
HtmlString HiddenFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression,
|
||||||
object htmlAttributes);
|
object htmlAttributes);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Id of the given expression.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="expression">The expression identifies the object for which the Id should be returned.</param>
|
||||||
|
/// <returns>New <see cref="HtmlString"/> containing the Id.</returns>
|
||||||
|
HtmlString IdFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns an HTML label element and the property name of the property that is represented by the specified
|
/// Returns an HTML label element and the property name of the property that is represented by the specified
|
||||||
/// expression.
|
/// expression.
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
: base.ComputeConvertEmptyStringToNull();
|
: base.ComputeConvertEmptyStringToNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string ComputeNullDisplayText()
|
||||||
|
{
|
||||||
|
return PrototypeCache.DisplayFormat != null
|
||||||
|
? PrototypeCache.DisplayFormat.NullDisplayText
|
||||||
|
: base.ComputeNullDisplayText();
|
||||||
|
}
|
||||||
|
|
||||||
protected override string ComputeDescription()
|
protected override string ComputeDescription()
|
||||||
{
|
{
|
||||||
return PrototypeCache.Display != null
|
return PrototypeCache.Display != null
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
public abstract class CachedModelMetadata<TPrototypeCache> : ModelMetadata
|
public abstract class CachedModelMetadata<TPrototypeCache> : ModelMetadata
|
||||||
{
|
{
|
||||||
private bool _convertEmptyStringToNull;
|
private bool _convertEmptyStringToNull;
|
||||||
|
private string _nullDisplayText;
|
||||||
private string _description;
|
private string _description;
|
||||||
private bool _isReadOnly;
|
private bool _isReadOnly;
|
||||||
private bool _isComplexType;
|
private bool _isComplexType;
|
||||||
|
|
||||||
private bool _convertEmptyStringToNullComputed;
|
private bool _convertEmptyStringToNullComputed;
|
||||||
|
private bool _nullDisplayTextComputed;
|
||||||
private bool _descriptionComputed;
|
private bool _descriptionComputed;
|
||||||
private bool _isReadOnlyComputed;
|
private bool _isReadOnlyComputed;
|
||||||
private bool _isComplexTypeComputed;
|
private bool _isComplexTypeComputed;
|
||||||
|
|
@ -62,6 +64,24 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed override string NullDisplayText
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!_nullDisplayTextComputed)
|
||||||
|
{
|
||||||
|
_nullDisplayText = ComputeNullDisplayText();
|
||||||
|
_nullDisplayTextComputed = true;
|
||||||
|
}
|
||||||
|
return _nullDisplayText;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_nullDisplayText = value;
|
||||||
|
_nullDisplayTextComputed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public sealed override string Description
|
public sealed override string Description
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -118,6 +138,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
return base.ConvertEmptyStringToNull;
|
return base.ConvertEmptyStringToNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual string ComputeNullDisplayText()
|
||||||
|
{
|
||||||
|
return base.NullDisplayText;
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual string ComputeDescription()
|
protected virtual string ComputeDescription()
|
||||||
{
|
{
|
||||||
return base.Description;
|
return base.Description;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
|
@ -20,6 +22,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
private int _order = DefaultOrder;
|
private int _order = DefaultOrder;
|
||||||
private IEnumerable<ModelMetadata> _properties;
|
private IEnumerable<ModelMetadata> _properties;
|
||||||
private Type _realModelType;
|
private Type _realModelType;
|
||||||
|
private string _simpleDisplayText;
|
||||||
|
|
||||||
public ModelMetadata([NotNull] IModelMetadataProvider provider,
|
public ModelMetadata([NotNull] IModelMetadataProvider provider,
|
||||||
Type containerType,
|
Type containerType,
|
||||||
|
|
@ -141,6 +144,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual string SimpleDisplayText
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_simpleDisplayText == null)
|
||||||
|
{
|
||||||
|
_simpleDisplayText = ComputeSimpleDisplayText();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _simpleDisplayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
set { _simpleDisplayText = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public virtual string TemplateHint { get; set; }
|
public virtual string TemplateHint { get; set; }
|
||||||
|
|
||||||
internal EfficientTypePropertyKey<Type, string> CacheKey
|
internal EfficientTypePropertyKey<Type, string> CacheKey
|
||||||
|
|
@ -177,6 +195,38 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
// return validatorProviders.SelectMany(provider => provider.GetValidators(this, validatorProviders));
|
// return validatorProviders.SelectMany(provider => provider.GetValidators(this, validatorProviders));
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
protected virtual string ComputeSimpleDisplayText()
|
||||||
|
{
|
||||||
|
if (Model == null)
|
||||||
|
{
|
||||||
|
return NullDisplayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
var stringResult = Convert.ToString(Model, CultureInfo.CurrentCulture);
|
||||||
|
if (stringResult == null)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stringResult.Equals(Model.GetType().FullName, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
return stringResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
var firstProperty = Properties.FirstOrDefault();
|
||||||
|
if (firstProperty == null)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstProperty.Model == null)
|
||||||
|
{
|
||||||
|
return firstProperty.NullDisplayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Convert.ToString(firstProperty.Model, CultureInfo.CurrentCulture);
|
||||||
|
}
|
||||||
|
|
||||||
private static EfficientTypePropertyKey<Type, string> CreateCacheKey(Type containerType, Type modelType, string propertyName)
|
private static EfficientTypePropertyKey<Type, string> CreateCacheKey(Type containerType, Type modelType, string propertyName)
|
||||||
{
|
{
|
||||||
// If metadata is for a property then containerType != null && propertyName != null
|
// If metadata is for a property then containerType != null && propertyName != null
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(typeof(Exception), metadata.ContainerType);
|
Assert.Equal(typeof(Exception), metadata.ContainerType);
|
||||||
Assert.True(metadata.ConvertEmptyStringToNull);
|
Assert.True(metadata.ConvertEmptyStringToNull);
|
||||||
|
Assert.Null(metadata.NullDisplayText);
|
||||||
Assert.Null(metadata.Description);
|
Assert.Null(metadata.Description);
|
||||||
Assert.Equal("model", metadata.Model);
|
Assert.Equal("model", metadata.Model);
|
||||||
Assert.Equal(typeof(string), metadata.ModelType);
|
Assert.Equal(typeof(string), metadata.ModelType);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue