如何在 ASP.NET Core Web API 中的每个方法中进行模型验证? [英] How to do model validation in every method in ASP.NET Core Web API?

查看:15
本文介绍了如何在 ASP.NET Core Web API 中的每个方法中进行模型验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Web API 进入 ASP.NET Core 2.0.我的第一个方法是登录:

////<摘要>///用于登录用户的 API 端点///</总结>///<param name="data">登录数据</param>///<returns>如果登录失败则未授权,如果登录成功则jwt令牌作为字符串</returns>[允许匿名][路由(登录")][HttpPost]公共 IActionResult 登录([FromBody]LoginData 数据){var token = _manager.ValidateCredentialsAndGenerateToken(data);如果(令牌==空){返回未授权();}别的{返回确定(令牌);}}

我的 LoginData 使用 DataAnnotations:

公共类 LoginData{[必需的][最大长度(50)]公共字符串用户名 { 获取;放;}[必需的]公共字符串密码{获取;放;}[必需的][最大长度(16)]公共字符串 IpAddress { 获取;放;}}

所以我的 ModelState 在登录发生时会自动填充,例如密码为空(当然在客户端也应该稍后对其进行验证).

最好的方法是什么

  • 检查模型状态,
  • 从所有错误中得到一个可读的字符串
  • 返回带有此错误的 BadRequest?

当然,我可以用辅助方法自己编写.但我想过一个过滤器吗?

解决方案

如何查看模型状态?

在 action 中检查控制器的 ModelState 以获取模型的状态.

<块引用>

从所有错误中获取可读字符串并返回带有此错误的 BadRequest?

使用 BadRequest(ModelState) 返回 HTTP 错误请求响应,该响应将检查模型状态并使用错误构造消息.

完成代码

////<摘要>///用于登录用户的 API 端点///</总结>///<param name="data">登录数据</param>///<returns>如果登录失败则未授权,如果登录成功则jwt令牌作为字符串</returns>[允许匿名][路线(登录")][HttpPost]公共 IActionResult 登录([FromBody]LoginData 数据){如果(模型状态.IsValid){var token = _manager.ValidateCredentialsAndGenerateToken(data);如果(令牌==空){返回未授权();} 别的 {返回确定(令牌);}}返回 BadRequest(ModelState);}

<块引用>

当然,我可以自己在辅助方法中编写所有内容...但我想过使用过滤器吗?

为了避免在需要模型验证的每个操作中重复 ModelState.IsValid 代码,您可以创建一个过滤器来检查模型状态并短路请求.

例如

public class ValidateModelAttribute : ActionFilterAttribute {公共覆盖无效 OnActionExecuting(ActionExecutingContext 上下文){如果(!context.ModelState.IsValid){context.Result = new BadRequestObjectResult(context.ModelState);}}}

可以直接应用于动作

[ValidateModel]//<-- 验证[允许匿名][路线(登录")][HttpPost]公共 IActionResult 登录([FromBody]LoginData 数据){var token = _manager.ValidateCredentialsAndGenerateToken(data);如果(令牌==空){返回未授权();} 别的 {返回确定(令牌);}}

或全局添加以应用于应检查模型状态的所有请求.

参考 ASP 中的模型验证.NET 核心 MVC

I am getting into ASP.NET Core 2.0 with Web API. One of my first methods are my login:

/// <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);
    }
}

My LoginData using 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; }
}

So my ModelState is well filled automatically when the login happens and e.g. the password is empty (of course on client side there should be a validation too for it later).

What is the best way to

  • check the model state,
  • getting a readable string out of all errors and
  • return a BadRequest with this error?

Of course I could write it all myself in a helper method. But I thought about a filter maybe?

解决方案

How to check the model state?

Check the controller's ModelState in the action to get the state of the model.

getting a readable string out of all errors and return a BadRequest with this error?

Use BadRequest(ModelState) to return HTTP bad request response which will inspect the model state and construct message using errors.

Completed code

/// <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);
}

Of course I could write it all myself in a helper method... But I thought about a filter maybe?

To avoid the repeated ModelState.IsValid code in every action where model validation is required you can create a filter to check the model state and short-circuit the request.

For example

public class ValidateModelAttribute : ActionFilterAttribute {
    public override void OnActionExecuting(ActionExecutingContext context) {
        if (!context.ModelState.IsValid) {
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
    }
}

Can be applied to the action directly

[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);
    }    
}

or added globally to be applied to all request where model state should be checked.

Reference Model validation in ASP.NET Core MVC

这篇关于如何在 ASP.NET Core Web API 中的每个方法中进行模型验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆