Validação de ModelBinder quebra no getter usando a reflexão
Eu corri em um problema que parece estar relacionado à reflexão e validação de fichário de modelo, eFormatterParameterBinding.ExecuteBindingAsync(..)
em particular, e embora eu possa usar um método para fazer o que eu quero, eu preferiria se eu pudesse usar uma propriedade.
Aqui estou procurando algumas informações sobre o processo de validação de fichário de modelo, por que não consigo fazer o que quero e como posso corrigir o problema ou contorná-lo.
A configuração
public class ModelBindingValidationBreaker
{
public ModelBindingValidationBreaker()
{
Properties = new List<string>();
}
public int A { get; set; }
public int B { get; set; }
public IList<string> Properties { get; set; }
/*// Uncomment to break the model binder validation!
public IList<PropertyInfo> PropertyInfos
{
get
{
return GetType()
.GetProperties()
.Where(pi => Properties.Contains(pi.Name))
.ToList();
}
}//*/
public IList<PropertyInfo> GetPropertyInfos()
{
return GetType()
.GetProperties()
.Where(pi => Properties.Contains(pi.Name))
.ToList();
}
public IList<int> LetterCounts
{
get
{
return Properties.Select(p => p.Length).ToList();
}
}
}
E um controlador com uma ação de post definida como esta
public void Post(ModelBindingValidationBreaker breaker){...}
Chame isso com esse tipo de json:
{
"Properties": [
"A"
],
"A": 1,
"B": 2
}
Se você entrar em ação, poderá ver que o disjuntor está instanciado corretamente e você pode ligarGetPropertyInfos()
sem qualquer problema.
Como se quebra
No entanto, se você descomente a propriedade PropertyInfos, a validação de fichário do modelo será interrompida. Eu adicionei um simples rastreador para descobrir isso. Mostra a seguinte saída relevante:
System.Web.Http.Action: ApiControllerActionSelector;SelectAction;Selected action 'Post(ModelBindingValidationBreaker breaker)'
System.Web.Http.ModelBinding: HttpActionBinding;ExecuteBindingAsync;
System.Web.Http.ModelBinding: FormatterParameterBinding;ExecuteBindingAsync;Binding parameter 'breaker'
System.Net.Http.Formatting: JsonMediaTypeFormatter;ReadFromStreamAsync;Type='ModelBindingValidationBreaker', content-type='application/json'
System.Net.Http.Formatting: JsonMediaTypeFormatter;ReadFromStreamAsync;Value read='OverPostCount.Models.ModelBindingValidationBreaker'
System.Web.Http.ModelBinding: FormatterParameterBinding;ExecuteBindingAsync;
System.Web.Http.ModelBinding: HttpActionBinding;ExecuteBindingAsync;
System.Web.Http.Controllers: CustomController;ExecuteAsync;
System.Net.Http.Formatting: DefaultContentNegotiator;Negotiate;Type='HttpError', formatters=[JsonMediaTypeFormatterTracer, FormUrlEncodedMediaTypeFormatterTracer, FormUrlEncodedMediaTypeFormatterTracer]
Que contém esta linha, quando você exclui o get_PropertyInfos ofensivo:
System.Web.Http.ModelBinding: FormatterParameterBinding;ExecuteBindingAsync;Parameter 'breaker' bound to the value 'OverPostCount.Models.ModelBindingValidationBreaker'
AdicionandoDataContract
e atributos relacionados como[IgnoreDataMember]
em Propriedades não corrige o problema. Nem[Bind(Exclude="Properties")]
do namespace mvc. Linq não parece ser o problema, já queLetterCount
não quebra a validação de fichário do modelo.
Minhas perguntas
Por que o getter PropertyInfos quebra o validador de fichário do modelo?Isso é um bug no asp.net web-api?Existe uma maneira de evitar essa quebra através de atributos, um validador de fichário de modelo personalizado, serviço ou similar?Basicamente eu não quero desligar a validação de ligação de modelo para toda a classe ou controlador, mas se eu pudesse desligá-lo para a propriedade Properties, isso seria ótimo!