Проверка валидатора ModelBinder прерывается с помощью отражения
Я столкнулся с проблемой, которая, по-видимому, связана с рефлексией и проверкой связующего элемента модели, иFormatterParameterBinding.ExecuteBindingAsync(..)
в частности, и хотя я могу использовать метод, чтобы делать то, что я хочу, я бы предпочел его, если бы я мог использовать свойство.
Здесь я ищу некоторое понимание процесса проверки подшивки моделей, почему я не могу делать то, что хочу, и как я могу решить проблему или обойти ее.
The setup
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()
без проблем.
How it breaks
Однако, если вы раскомментируете свойство 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'
ДобавлениеDataContract
и связанные атрибуты, такие как[IgnoreDataMember]
на свойства не решает проблему. Ни один не делает[Bind(Exclude="Properties")]
из пространства имен MVC. Linq, похоже, не является проблемой, так какLetterCount
не нарушает проверку связывателя модели.
My questions
Why does the PropertyInfos getter break the model binder validator? Is this a bug in the Asp.NET web-api? Is there a way to prevent this breakage through attributes, a custom model binder validator, service or similar?По сути, я не хочу отключать проверку привязки модели для всего класса или контроллера, но если бы я мог отключить ее для свойства Properties, это было бы здорово!