при возникновении ошибки привязки - например, недопустимая строка для привязки к guid - Состояние модели содержит только ошибки привязки, но не других ошибок - требуется атрибут или MaxLength и т. Д.Это что-то ожидаемое?
Это не правда.Настоящая причина в том, что вы обрабатываете JSON полезную нагрузку .Сначала полезная нагрузка json должна быть десериализована в ICollection<SkillBindDto>
, а затем валидатор может ее проверить.
При обработке вашей полезной нагрузки с недопустимым свойством GUID
десериализация завершается неудачно слишком рано , поэтому больше не будет привязываться / проверяться для других свойств.
Есть ли способ получить все ошибки состояния модели за одну поездку?
Как я уже говорил выше, проблемапроисходит из-за сбоя JSON Deserailziation.
Если вы хотите использовать формат JSON, вы сообщаете MVC, как обрабатывать недопустимое свойство.Например, создайте пользовательский JsonConverter
:
public class MyCustomConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var dt= reader.Value;
... // because the processing rules depends on your business,
... // I can't write all the codes here.
... // e.g.
... // create a null(object) or default(value) if invalid
}
}
Easy Walkaround
В качестве более простого обхода вы можете вместо этого отправить полезную нагрузку формы application/json
.
Форма полезной нагрузки кодируется в виде пар ключ-значение, разделенных символом «&», с ключом «=» между ключом и значением, которое выглядит как строка запроса.Когда вы отправляете HTML <form />
в старые времена, вы фактически отправляете полезную нагрузку формы.
Frist, удалите атрибут [FromBody]
в своем действии:
[HttpPost()]
public async Task<ActionResult<IReadOnlyCollection<SkillDto>>> Create(<strike>[FromBody]</strike>ICollection<SkillBindDto> skills, CancellationToken cancellationToken)
{
...
}
, а затем отправьте полезную нагрузку в формате application/x-www-form-urlencoded
.Вы можете использовать new FormData(formElementId)
для создания такой формы данных.Я создаю вспомогательную функцию, которая отображает JSON для данных формы:
function createFormPayload(name,o){
var payload = {};
function _objectNotNull(value){
return value !== null && typeof value === "object";
}
function _create(prefix,obj) {
for(var prop in obj) {
if (obj.hasOwnProperty(prop)) {
var key = "";
if(prefix){
key = isNaN(prop)? key = prefix + "." + prop : key = prefix + ".[" + prop + "]";
}else{
key = isNaN(prop)? key = prop : key = "[" + prop + "]";
}
var value = obj[prop];
if(_objectNotNull(value))
_create(key, value);
else
payload[key]=value;
}
}
};
_create(name,o);
return payload;
}
И теперь мы можем отправить skills
объекту данных формы:
var skills= [
{
"SectionId" : "0c2d3928-aff2-44da-blaaah-blaaah",
"Name" : "",
"Info" : "Test Info",
"Tags" : ["tag 1", "tag 2"]
}, {
"SectionId" : "0c2d3928-aff2-44da-blaaah-blaaah",
"Name" : "",
"Info" : "Test Info 2",
"Tags" : ["tag 3", "tag 2"]
}
];
var data = createFormPayload("",skills) ;
$.ajax({
type: "POST",
url: "/xxx/create",
data: data,
success: function(r){
console.log(r);
},
});
Демо
При отправке вышеуказанных умений фактическая полезная нагрузка будет:
POST https://localhost:5001/Home/Create
Content-Type: application/x-www-form-urlencoded
[0].SectionId=0c2d3928-aff2-44da-blaaah-blaaah&[0].Name=&[0].Info=Test Info&[0].Tags[1]=tag1&[0].Tags[2]=tag2&[1].SectionId=0c2d3928-aff2-44da-blaaah-blaaah&[1].Name=&[1].Info=TestInfo2&[1].Tags[1]=tag3&[1].Tags[2]=tag 2
И тогда вы получите ответ, который описывает все ошибки: