【问题标题】:asp.net core validation after filters过滤器后的asp.net核心验证
【发布时间】:2019-09-08 01:16:05
【问题描述】:

我想在模型验证之前但在模型绑定之后为我们服务中的所有 API(asp.net 核心)运行一些自定义逻辑。这可能吗?我尝试了一个 ActionFilter,但它在验证后被调用。资源过滤器也对我们不起作用。感谢您的帮助。

【问题讨论】:

  • 为什么要在模型验证之前运行?模型验证是模型绑定的一部分。
  • @Nairooz - 我在下面的回答解决了你的问题吗?

标签: asp.net-mvc asp.net-core asp.net-core-2.0


【解决方案1】:

Web API controllers don't have to check ModelState.IsValid 如果它们具有 [ApiController] 属性。在这种情况下,当模型状态无效时,会返回包含问题详细信息的自动 HTTP 400 响应。

实现您想要的一种方法是抑制这种行为。

将以下代码添加到 ConfigureServices:

        services.Configure<ApiBehaviorOptions>(options =>
        {
            options.SuppressModelStateInvalidFilter = true;
        });

然后您可以将代码添加到过滤器 - 例如:

public class SampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // do something before the action executes
        if(context.ActionArguments != null && context.ActionArguments.Count > 0)
        {
            //WARNING - you should add "safe" code to access the dictionary
            //I have hardcoded the parameter name (data) here for sample only.
            var model = context.ActionArguments["data"];
        }
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // do something after the action executes
    }
}

当然,您还需要应用过滤器 - 在下面的示例中,我已全局应用它。如果你愿意,你可以更具体。

services.AddMvc(
            options => options.Filters.Add(new SampleActionFilter())
            ).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

在您的控制器代码中,您还可以根据需要进一步使用 TryValidateModel 方法,如下所示:

[Route("api/[controller]")]
[ApiController]
public class ProcessController : ControllerBase
{
    [HttpPost]
    public IActionResult Contact(FormDataModel data)
    {
        bool validated = TryValidateModel(data);

        if (!ModelState.IsValid)
        {
            ModelState.AddModelError("", "Id cannot be empty..");
            return Ok();
        }

        return Ok();
    }
}

希望这有助于解决您的问题。

【讨论】:

    最近更新 更多