1

我遇到了一个似乎与反射和模型绑定器验证有关的问题,FormatterParameterBinding.ExecuteBindingAsync(..)特别是,虽然我可以使用方法来做我想做的事情,但如果我可以使用属性,我会更喜欢它。

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

设置

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();
        }
    }
}

和一个具有这样定义的发布操作的控制器

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

用这种 json 调用它:

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

如果您进入该操作,您可以看到断路器已正确实例化,您可以GetPropertyInfos()毫无问题地调用。

它是如何破裂的

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

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'

在 Properties 上添加DataContract, 和相关属性[IgnoreDataMember]并不能解决问题。[Bind(Exclude="Properties")]从 mvc 命名空间也没有。Linq 似乎不是问题,因为LetterCount它不会破坏模型绑定器验证。

我的问题

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

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

4

1 回答 1

4

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

于 2012-08-08T08:39:28.073 回答