C# 使用反射在getter上中断ModelBinder验证
我遇到了一个问题,它似乎与反射和模型绑定器验证有关,尤其是C# 使用反射在getter上中断ModelBinder验证,c#,reflection,asp.net-mvc-4,asp.net-web-api,model-binding,C#,Reflection,Asp.net Mvc 4,Asp.net Web Api,Model Binding,我遇到了一个问题,它似乎与反射和模型绑定器验证有关,尤其是FormatterParameterBinding.ExecuteBindingAsync(..),虽然我可以使用一个方法来做我想做的事情,但如果我可以使用一个属性,我更希望它 在这里,我想了解一些关于模型绑定器验证过程的见解,为什么我不能做我想做的事情,以及如何解决这个问题,或者绕开它 设置 public class ModelBindingValidationBreaker { public ModelBindingValid
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();
}
}
}
用这种json调用它:
{
"Properties": [
"A"
],
"A": 1,
"B": 2
}
如果您执行该操作,您可以看到断路器已正确实例化,并且可以调用GetPropertyInfos()
,而不会出现任何问题
它是如何断裂的
但是,如果取消对PropertyInfo属性的注释,则模型绑定器验证将中断。我添加了一个简单的跟踪程序来解决这个问题。它显示以下相关输出:
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_PropertyFos时,它反而包含此行:
System.Web.Http.ModelBinding: FormatterParameterBinding;ExecuteBindingAsync;Parameter 'breaker' bound to the value 'OverPostCount.Models.ModelBindingValidationBreaker'
在属性上添加DataContract
和相关属性,如[IgnoreDataMember]
,并不能解决此问题。mvc命名空间中也没有[Bind(Exclude=“Properties”)]
。Linq似乎不是问题,因为LetterCount
不会破坏模型绑定器验证
我的问题
基本上我不想关闭整个类或控制器的模型绑定验证,但是如果我可以关闭Properties属性的模型绑定验证,那就太好了 作为一般规则,您应该避免在用于模型绑定的类中使用具有其他复杂类型属性的复杂类,如PropertyFos,但您应该使用仅包含模型绑定过程所需属性的简单类,而且整个对象图不应包含循环。模型绑定过程为不同目的分析属性类型(验证属性等)。我可能会重复分析eac属性类型中包含的子属性…因此包含循环和许多其他.net类型的复杂.net类可能会破坏它。
尝试将属性属性设置为内部属性,或将其转换为一种方法,使其不会被任何模型绑定器组件处理 作为一般规则,您应该避免在用于模型绑定的类中使用具有其他复杂类型属性的复杂类,如PropertyFos,但您应该使用仅包含模型绑定过程所需属性的简单类,而且整个对象图不应包含循环。模型绑定过程为不同目的分析属性类型(验证属性等)。我可能会重复分析eac属性类型中包含的子属性…因此包含循环和许多其他.net类型的复杂.net类可能会破坏它。
尝试将属性属性设置为内部属性,或将其转换为一种方法,使其不会被任何模型绑定器组件处理 我想知道为什么我会如此费心地问一些无关紧要的问题。人们只是想磨磨蹭蹭,似乎并不真的在乎帮助别人。我不知道为什么我会这么麻烦地问一些无关紧要的问题。人们只是想磨磨蹭蹭,似乎并不真正关心帮助。老实说,这是非常不令人满意的。我所听到的是,对于我的所有模型绑定,我应该只使用哑类和结构,这意味着我的所有模型。这意味着我不得不使用哑DTO。这可能是最好的实践和建议。但如果这不符合我的设想呢?C#是一种面向对象语言,应该允许我绑定到具有复杂属性的智能类。他们所能提供的至少是一种通过属性禁用特定属性的模型绑定验证的方法,对于像我这样的叛逆者来说。模型绑定器到底在做什么,需要它进入我的getter?是什么导致它崩溃?当我在它上面有IgnoreDataMemberAttribute时,它没有被绑定,所以它不应该被验证,代码也不应该中断。我看你还没完成。你从错误的角度看待这个问题。您不限于使用struct!不推荐在Presentation层中使用复杂的业务类。在表示层中,您使用的是viewmodels,而不是业务类。您可以在表示层中自由添加所需的complkexity。模型绑定过程涉及对象树(属性中包含的子对象)。不允许循环,因为所有算法都无法识别指向同一对象并复制该对象的属性。模型绑定和验证算法递归探索对象树以查找验证属性和元数据。这意味着,如果您使用的属性的数据类型是一个具有数百个属性的复杂系统类型,那么该复杂数据类型将与其所有属性一起递归探索……以及它包含循环或出现安全问题的可能性(如果您没有完全运行)几乎100%的忽略属性应该只影响序列化-反序列化阶段,而不是验证。老实说,这是非常不令人满意的。我所听到的是,对于我的所有模型绑定,我应该只使用哑类和结构,这意味着我的所有模型。这意味着我不得不使用哑DTO。这可能是最好的实践和建议。但如果这不符合我的设想呢?C#是一种面向对象语言,应该允许我绑定到具有复杂属性的智能类。他们至少可以提供一种通过attrib禁用特定属性的模型绑定验证的方法
System.Web.Http.ModelBinding: FormatterParameterBinding;ExecuteBindingAsync;Parameter 'breaker' bound to the value 'OverPostCount.Models.ModelBindingValidationBreaker'