Ho un modello semplice:Come disattivare ModelMetadata.IsRequired da essere sempre vero per non annullabile tipo di valore
public class Sample
{
public bool A { get; set; }
[Required]
public bool B { get; set; }
}
A non è, ovviamente, necessario. Pertanto, per la convalida è stato impostato DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false
in Global.asax.
Ho anche un semplice aiuto html che consente di stampare vero o falso, se è richiesto il modello:
public static class HtmlHelperExtensions
{
public static MvcHtmlString IsRequired<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
return new MvcHtmlString(metadata.IsRequired.ToString());
}
}
Ho anche scritto al fine di mostrare il mio problema:
@model MvcApplication10.Models.Sample
A: @Html.IsRequired(m => m.A), B: @Html.IsRequired(m => m.B)
mi sarei aspettato questo per stampare A: false, B: true
, tuttavia, stampa effettivamente A: true, B: true
.
C'è un modo per rendere questa stampa il mio risultato previsto? IsRequired
sembra sempre restituire true anche se non ho impostato esplicitamente lo RequiredAttribute
. Lo docs dichiara che è vero per i tipi di valore non annullabile per impostazione predefinita. Come mai non c'è un modo semplice per impostare questo a falso come possiamo con la convalida?
EDIT: Potrei scrivere un provider personalizzato come questo, ma mi chiedevo se ci fosse un modo "facile" intorno a questo:
public class ExtendedDataAnnotationsModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
private static bool addImplicitRequiredAttributeForValueTypes = false;
public static bool AddImplicitRequiredAttributeForValueTypes
{
get
{
return addImplicitRequiredAttributeForValueTypes;
}
set
{
addImplicitRequiredAttributeForValueTypes = value;
}
}
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
var result = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
if (!AddImplicitRequiredAttributeForValueTypes && modelType.IsValueType && !attributes.OfType<RequiredAttribute>().Any())
{
result.IsRequired = false;
}
return result;
}
}
In MVC5 impostando semplicemente 'DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false' fa ora hanno l'effetto atteso di non aggiungere automaticamente' RequiredAttribute' per il valore non annullabile tipi. – Cocowalla