ModelBindervalidation使用reflection在getter上中断

我遇到了一个似乎与reflection和模型绑定器validation有关的问题,特别是FormatterParameterBinding.ExecuteBindingAsync(..) ,虽然我可以使用一个方法来做我想要的但如果我可以使用我会更喜欢它财产。

在这里,我正在寻找对模型绑定器validation过程的一些见解,为什么我无法做我想做的事情以及如何解决问题,或者解决它。

设置

 public class ModelBindingValidationBreaker { public ModelBindingValidationBreaker() { Properties = new List(); } public int A { get; set; } public int B { get; set; } public IList Properties { get; set; } /*// Uncomment to break the model binder validation! public IList PropertyInfos { get { return GetType() .GetProperties() .Where(pi => Properties.Contains(pi.Name)) .ToList(); } }//*/ public IList GetPropertyInfos() { return GetType() .GetProperties() .Where(pi => Properties.Contains(pi.Name)) .ToList(); } public IList LetterCounts { get { return Properties.Select(p => p.Length).ToList(); } } } 

并且控制器的后期动作定义如下

 public void Post(ModelBindingValidationBreaker breaker){...} 

用这种json调用它:

 { "Properties": [ "A" ], "A": 1, "B": 2 } 

如果您单步执行操作,您可以看到断路器已正确实例化,您可以毫无问题地调用GetPropertyInfos()

怎么打破

但是,如果取消注释PropertyInfos属性,则模型绑定器validation会中断。 我添加了一个简单的跟踪器来解决这个问题。 它显示以下相关输出:

 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] 

当您排除有问题的get_PropertyInfos时,其中包含此行:

 System.Web.Http.ModelBinding: FormatterParameterBinding;ExecuteBindingAsync;Parameter 'breaker' bound to the value 'OverPostCount.Models.ModelBindingValidationBreaker' 

添加DataContract以及属性上的[IgnoreDataMember]等相关属性无法解决问题。 [Bind(Exclude="Properties")]也不是来自mvc命名空间。 Linq似乎不是问题,因为LetterCount不会破坏模型绑定器validation。

我的问题

  1. 为什么PropertyInfos getter会破坏模型绑定器validation器?
  2. 这是Asp.NET web-api中的错误吗?
  3. 有没有办法通过属性,自定义模型绑定器validation器,服务或类似方法来防止这种破坏?

基本上我不想为整个类或控制器关闭模型绑定validation,但如果我可以为Properties属性关闭它,那就太棒了!

作为一般规则,您应该避免使用像PropertyInfos这样的复杂类,这些类具有其他复杂类型的属性…在用于模型绑定的类中,但是您应该只使用包含模型绑定过程所需的JUST THE PROPERTIES的简单类整个对象图应该不包含循环。 模型绑定过程分析不同目的的属性类型(validation属性等),我可以重新分析eac属性类型中包含的子属性…所以复杂的.net类包含循环和很多其他.net类型可能会破坏它。 尝试将属性PropertyInfos设置为内部或将其转换为方法,以便任何模型绑定器组件都不会对其进行处理。