Walidacja ModelBinder zrywa na getterze za pomocą odbicia
Natknąłem się na problem, który wydaje się być związany z walidacją refleksji i modelu spoiwaFormatterParameterBinding.ExecuteBindingAsync(..)
w szczególności, i chociaż mogę użyć Metody, aby zrobić to, co chcę, wolałbym, aby móc użyć Własności.
Tutaj szukam wglądu w proces walidacji modelu spoiwa, dlaczego nie jestem w stanie zrobić tego, co chcę i jak mogę rozwiązać problem lub obejść go.
Ustawić
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();
}
}
}
I kontroler z postem zdefiniowanym w ten sposób
public void Post(ModelBindingValidationBreaker breaker){...}
Nazwij to tym jsonem:
{
"Properties": [
"A"
],
"A": 1,
"B": 2
}
Jeśli wkroczysz do akcji, zobaczysz, że łamacz jest poprawnie utworzony i możesz zadzwonićGetPropertyInfos()
bez problemu.
Jak się łamie
Jeśli jednak usuniesz komentarz z właściwości PropertyInfos, sprawdzanie poprawności modelu zostanie przerwane. Dodałem prosty znacznik, żeby to rozgryźć. Pokazuje następujące istotne dane wyjściowe:
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]
Który zamiast tego zawiera tę linię, gdy wykluczasz obraźliwe get_PropertyInfos:
System.Web.Http.ModelBinding: FormatterParameterBinding;ExecuteBindingAsync;Parameter 'breaker' bound to the value 'OverPostCount.Models.ModelBindingValidationBreaker'
DodawanieDataContract
i podobne atrybuty jak[IgnoreDataMember]
na Właściwości nie rozwiązuje problemu. Ani nie[Bind(Exclude="Properties")]
z przestrzeni nazw mvc. Linq nie wydaje się być problemem, ponieważLetterCount
nie przerywa walidacji modelu spoiwa.
Moje pytania
Dlaczego getter PropertyInfos przerywa walidator modelu?Czy jest to błąd w web-api Asp.NET?Czy istnieje sposób na uniknięcie tego złamania przez atrybuty, niestandardowy model walidatora, usługę lub podobny?Zasadniczo nie chcę wyłączać sprawdzania poprawności wiązania modelu dla całej klasy lub kontrolera, ale jeśli mógłbym go wyłączyć dla właściwości Właściwości, byłoby świetnie!