我使用的是net core 2.2 web api,我想为每个请求验证我的主体。数据类型字符串的验证工作正常,但int和decimal的验证工作不正常。
我的Model类如下:
public class IcuTherapyO2Request
{
[Required(ErrorMessage = "Mr Number is required")]
public int mrNo { get; set; }
[Required(ErrorMessage = "Type is required")]
public string type { get; set; }
}
我的控制器
// create
#region
[HttpPost("create")]
public async Task<IActionResult> create([FromBody] IcuTherapyO2Request icuTherapyO2Request)
{
try
{
var claimsIdentity = this.User.Identity as ClaimsIdentity;
var userId = claimsIdentity.FindFirst("id")?.Value;
icuTherapyO2Request.createdBy = userId;
var response = await _icuIORepository.create(icuTherapyO2Request);
return Ok(response);
}
catch (Exception ex)
{
return StatusCode(500, new Error { });
}
}
#endregion
案例1:我忘记在post-body 中传递字符串类型的对象
{
mrNo: 2
}
现在我得到以下错误:{"错误":{"类型":["类型是必需的";]},"标题":"出现一个或多个验证错误&";,"状态":400,"traceId":"0HM66ODDT3V8O:000000002";}
案例2:我忘记在post-body 中传递类型为number的对象
{
type: "string"
}
这里一切都很好,即使mrNo缺少
我终于找到了问题的解决方案。以下是发生的情况,对于int和decimal类型,即使对象没有通过,asp.net核心模型也会将0指定为默认值,所以我添加了更多的验证,使用RANGE只接受从1开始的值。
我更新的模型如下:
public class IcuTherapyO2Request
{
[Range(1, int.MaxValue, ErrorMessage = "Mr Number is required")] // this makes it to work
[Required(ErrorMessage = "Mr Number is required")]
public int mrNo { get; set; }
[Required(ErrorMessage = "Type is required")]
public string type { get; set; }
}
现在,随着问题用控制器更新,我们可以谈谈了。
虽然我不知道为什么你对某些类型的验证有效(你没有回答关于验证方面的问题),但根据你提供的代码,我们可以告诉你:
DataAnnotations
属性用于ASP.NET*,以便在将数据发布回服务器时构建ModelState
(好吧,不仅是发布,更不用说)。这就是所谓的model binding
过程,它发生在幕后,允许您将动作的参数指定为具有给定类型的对象
在这个特定的例子中,通过发送一个POST,其格式为例如
@model WebApplication_NumberValidation.Models.IcuTherapyO2Request
<form asp-action="create" method="post">
<input asp-for="mrNo" />
<span asp-validation-for="mrNo" class="text-danger"></span>
...
<button typr="submit">FIRE</button>
</form>
您的浏览器正在使用带有主体的POST <server>/<controller>/create
调用服务器
{
"mrNo": something
...
}
请求已发送,服务器调用<controller>/create
([HttpPost("create")]
)。由于模型绑定,服务器接收到的FromBody
数据用于创建IcuTherapyO2Request icuTherapyO2Request
,DataAnnotations
用于更新ModelState
。
现在服务器需要向您发送一些回报,而这正是您做错的时候。您正在返回
Ok(response)
,它将向您发送response
的串行状态以及200 HTTP代码。这不是你想做的。您希望向用户发送相同的模型、相同的数据验证视图,以便服务器能够使用
ModelState
来填充HTML。CCD_ 14包含了所有关于模型验证的数据。你应该这样做:
{
Console.WriteLine(ModelState.IsValid);
if (ModelState.IsValid)
{
// Do whatever You do BUT
return View();
}
return View(icuTherapyO2Request); // icuTherapyO2Request from action's parameter
}
如果需要,ModelState
也可以用于AddModelError
手动添加模型错误。
这里的关键点是:
- 返回具有相同模型的相同视图作为对用户的响应,这将显示一个新页面,但具有旧模型+更新的模型状态
- 不返回仅用于API的
OK
(或者如果您在客户端浏览器上使用JS处理该响应)。否则,用户将停留在同一页面上,服务器上没有新的HTML。因此,除非您正在执行一些客户端代码,否则您可能需要返回一些View
(带有"Your form has something"的内容)