Kov*_*ovu 10 c# modelstate .net-core asp.net-core asp.net-core-webapi
我正在使用Web API进入ASP.Net Core 2.0.
我的第一个方法之一是我的登录:
/// <summary>
/// API endpoint to login a user
/// </summary>
/// <param name="data">The login data</param>
/// <returns>Unauthorizied if the login fails, The jwt token as string if the login succeded</returns>
[AllowAnonymous]
[Route("login")]
[HttpPost]
public IActionResult Login([FromBody]LoginData data)
{
var token = _manager.ValidateCredentialsAndGenerateToken(data);
if (token == null)
{
return Unauthorized();
}
else
{
return Ok(token);
}
}
Run Code Online (Sandbox Code Playgroud)
我LoginData使用DataAnnotations:
public class LoginData
{
[Required]
[MaxLength(50)]
public string Username { get; set; }
[Required]
public string Password { get; set; }
[Required]
[MaxLength(16)]
public string IpAddress { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
因此,ModelState当登录发生时,我的信息会自动填满,例如密码为空(当然在客户端也应该对其进行验证).
我的问题是:
a)检查模型状态的最佳方法是什么,b)从所有错误中获取可读字符串并且C)返回带有此错误的BadRequest?
当然我可以用辅助方法自己写出来......但我想过一个过滤器可能吗?
Nko*_*osi 18
如何检查模型状态?
检查操作中的控制器ModelState以获取模型的状态.
从所有错误中获取可读字符串并返回带有此错误的BadRequest?
使用BadRequest(ModelState)返回将检查模型的状态,并使用错误的构造消息HTTP错误的请求响应.
完成的代码
/// <summary>
/// API endpoint to login a user
/// </summary>
/// <param name="data">The login data</param>
/// <returns>Unauthorizied if the login fails, The jwt token as string if the login succeded</returns>
[AllowAnonymous]
[Route("login")]
[HttpPost]
public IActionResult Login([FromBody]LoginData data) {
if(ModelState.IsValid) {
var token = _manager.ValidateCredentialsAndGenerateToken(data);
if (token == null) {
return Unauthorized();
} else {
return Ok(token);
}
}
return BadRequest(ModelState);
}
Run Code Online (Sandbox Code Playgroud)
当然我可以用辅助方法自己写出来......但我想过一个过滤器可能吗?
为了避免在ModelState.IsValid需要进行模型验证的每个操作中重复代码,您可以创建一个过滤器来检查模型状态并使请求短路.
例如
public class ValidateModelAttribute : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext context) {
if (!context.ModelState.IsValid) {
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
}
Run Code Online (Sandbox Code Playgroud)
可以直接应用于动作
[ValidateModel] //<-- validation
[AllowAnonymous]
[Route("login")]
[HttpPost]
public IActionResult Login([FromBody]LoginData data) {
var token = _manager.ValidateCredentialsAndGenerateToken(data);
if (token == null) {
return Unauthorized();
} else {
return Ok(token);
}
}
Run Code Online (Sandbox Code Playgroud)
或全局添加以应用于应检查模型状态的所有请求.
要检查模型状态是否有效,请使用 ModelState 属性(由 Controller 类继承的 ControllerBase 类公开)
ModelState.IsValid
Run Code Online (Sandbox Code Playgroud)
要从 ModelState 中获取错误,您可以从字典中过滤掉错误并将它们作为列表返回
var errors = ModelState
.Where(a => a.Value.Errors.Count > 0)
.SelectMany(x => x.Value.Errors)
.ToList();
Run Code Online (Sandbox Code Playgroud)
一种选择是验证每个方法/控制器中的状态,但我建议您在基类中实现验证,该基类验证
OnActionExecuting 方法中的模型,如下所示
public class ApiController : Controller
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!ModelState.IsValid)
{
var errors = ModelState
.Where(a => a.Value.Errors.Count > 0)
.SelectMany(x => x.Value.Errors)
.ToList();
context.Result = new BadRequestObjectResult(errors);
}
base.OnActionExecuting(context);
}
}
Run Code Online (Sandbox Code Playgroud)
然后每个应该具有自动模型状态验证的控制器都从基类继承
public class TokenController : ApiController
{
/// <summary>
/// API endpoint to login a user
/// </summary>
/// <param name="data">The login data</param>
/// <returns>Unauthorizied if the login fails, The jwt token as string if the login succeded</returns>
[AllowAnonymous]
[Route("login")]
[HttpPost]
public IActionResult Login([FromBody]LoginData data)
{
var token = _manager.ValidateCredentialsAndGenerateToken(data);
if (token == null)
{
return Unauthorized();
}
else
{
return Ok(token);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我强烈建议使用[ApiController]和其他有助于简化基于Web API的项目中的验证的属性。
[ApiController]此属性在进入方法之前会先对模式进行所有基本验证。因此,如果您想进行某种形式的自定义验证,则只需检查模态。
| 归档时间: |
|
| 查看次数: |
11689 次 |
| 最近记录: |