当对对象执行模型绑定时,如果任何对象的属性存在类型不匹配,则框架似乎将返回null。例如,考虑这个简单的例子:
public class Client
{
public string Name { get; set; }
public int Age { get; set; }
public DateTime RegistrationDate { get; set; }
}
public class ClientController : Controller
{
[HttpPatch]
public IActionResult Patch([FromBody]Client client)
{
return Ok("Success!");
}
}
如果我提交" asdf"对于HTTP请求中的Age属性,无论为其他属性提交了什么,整个客户端参数在Patch方法中都将为null。 RegistrationDate属性也是一样。因此,当您的控制器操作中的FromBody参数为null时,您如何知道哪些错误导致模型绑定失败(在这种情况下,哪个提交的属性具有错误的类型)?
答案 0 :(得分:9)
对于之前的错误答案感到抱歉。正如您所说,MVC核心默认改变了MVC API处理模型绑定的方式。您可以使用当前的ModelState查看哪些项目失败以及出于何种原因。
[HttpPatch]
[Route("Test")]
public IActionResult PostFakeObject([FromBody]Test test)
{
foreach (var modelState in ViewData.ModelState.Values)
{
foreach (var error in modelState.Errors)
{
//Error details listed in var error
}
}
return null;
}
}
错误消息中存储的异常将显示如下内容:
Exception = {Newtonsoft.Json.JsonReaderException:无法转换 字符串到整数:饼。路径'年龄',第1行,第28位 Newtonsoft.Json.JsonReader.ReadInt32String(String s)at Newtonsoft.Json.JsonTextReader.FinishReadQuotedNumber(ReadType readType)...
但是,正如上面的评论中所述,Microsoft文档解释了以下内容:
如果绑定失败,MVC不会抛出错误。每一个行动 接受用户输入应该检查ModelState.IsValid属性。
注意:控制器的ModelState属性中的每个条目都是a ModelStateEntry包含Errors属性。这很少需要 自己查询这个集合。请改用ModelState.IsValid。 https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding
答案 1 :(得分:1)
只是一个注释,你可以用
写同样的逻辑var errors = ViewData.ModelState.Values.SelectMany(x => x.Errors );
foreach(var err in errors) {
// Error details listed in err (type is Microsoft.AspNetCore.Mvc.ModelBinding.ModelError)
}
而且它比上一个答案中的嵌套 foreach 循环更紧凑、更高效。