由于 ModelBinding在动作过滤器之前运行,直接使用 context.ActionArguments["parameter"]  获取模型对象

This article shows how to use an ActionFilter to validate the model from a HTTP POST request in an ASP.NET Core MVC application.

Code: https://github.com/damienbod/AngularAutoSaveCommands

2019-07-31: Updated to ASP.NET Core 3.0 Preview 7, Updated to Angular 8.1.3
2019-02-16: Updated to Angular 7.2.4, ASP.NET Core 2.2 nuget packages
2018-11-22: Updated to Angular 7.1.0, nuget packages
2018-09-28: Updated to ASP.NET Core 2.1.4 and Angular 6.1.9
2018-06-16: Updated to ASP.NET Core 2.1 and Angular 6.0.5
2018-02-11: Updated to ASP.NET Core All 2.0.5 and Angular 5.2.4
2017-08-19: Updated to ASP.NET Core 2.0 and Angular 4.3.5
2017.02.03: Updated to Angular 2.4.5 and webpack 2.2.1, VS2017 RC3, msbuild3
2016.12.23: Updated to Visual Studio 2017 and ASP.NET Core 1.1

Other articles in this series:

  1. Implementing UNDO, REDO in ASP.NET Core
  2. Angular Auto Save, Undo and Redo
  3. ASP.NET Core Action Arguments Validation using an ActionFilter

In an ASP.NET Core MVC application, custom validation logic can be implemented in an ActionFilter. Because the ActionFilter is processed after the model binding in the action execution, the model and action parameters can be used in an ActionFilter without having to read from the Request Body, or the URL.

The model can be accessed using the context.ActionArguments dictionary. The key for the property has to match the parameter name in the MVC Controller action method. Ryan Nowak also explained in this issue, that the context.ActionDescriptor.Parameters can also be used to access the request payload data.

If the model is invalid, the context status code is set to 400 (bad request) and the reason is added to the context result using a ContentResult object. The request is then no longer processed but short circuited using the terminology from the ASP.NET Core documentation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using System;
using System.IO;
using System.Text;
using AngularAutoSaveCommands.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
 
namespace AngularAutoSaveCommands.ActionFilters
{
    public class ValidateCommandDtoFilter : ActionFilterAttribute
    {
        private readonly ILogger _logger;
 
        public ValidateCommandDtoFilter(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger("ValidatePayloadTypeFilter");
        }
 
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var commandDto = context.ActionArguments["commandDto"] as CommandDto;
            if (commandDto == null)
            {
                context.HttpContext.Response.StatusCode = 400;
                context.Result = new ContentResult()
                {
                    Content = "The body is not a CommandDto type"
                };
                return;
            }
 
            _logger.LogDebug("validating CommandType");
            if (!CommandTypes.AllowedTypes.Contains(commandDto.CommandType))
            {
                context.HttpContext.Response.StatusCode = 400;
                context.Result = new ContentResult()
                {
                    Content = "CommandTypes not allowed"
                };
                return;
            }
 
            _logger.LogDebug("validating PayloadType");
            if (!PayloadTypes.AllowedTypes.Contains(commandDto.PayloadType))
            {
                context.HttpContext.Response.StatusCode = 400;
                context.Result = new ContentResult()
                {
                    Content = "PayloadType not allowed"
                };
                return;
            }
 
            base.OnActionExecuting(context);
        }
    }
}

The ActionFilter is added to the services in the Startup class. This is not needed if the ActionFilter is used directly in the MVC Controller.

1
services.AddScoped<ValidateCommandDtoFilter>();

The filter can then be used in the MVC Controller using the ServiceFilter attribute. If the commandDto model is invalid, a BadRequest response is returned without processing the business in the action method.

1
2
3
4
5
6
7
8
[ServiceFilter(typeof(ValidateCommandDtoFilter))]
[HttpPost]
[Route("Execute")]
public IActionResult Post([FromBody]CommandDto commandDto)
{
    _commandHandler.Execute(commandDto);
    return Ok(commandDto);
}

Links

https://docs.asp.net/en/latest/mvc/controllers/filters.html

https://github.com/aspnet/Mvc/issues/5260#issuecomment-245936046

https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Abstractions/Filters/ActionExecutingContext.cs

.net core 从 ActionFilterAttribute 获取Request.Body 的正确方式的更多相关文章

  1. 深入探究ASP.NET Core读取Request.Body的正确方式

    前言 相信大家在使用ASP.NET Core进行开发的时候,肯定会涉及到读取Request.Body的场景,毕竟我们大部分的POST请求都是将数据存放到Http的Body当中.因为笔者日常开发所使用的 ...

  2. @Spring MVC 中几种获取request和response的方式

    1.最简单方式:处理方法入参 例如: @RequestMapping("/test") @ResponseBody public void saveTest(HttpServlet ...

  3. Struts2获取request的几种方式汇总

    Struts2获取request三种方法 struts2里面有三种方法可以获取request,最好使用ServletRequestAware接口通过IOC机制注入Request对象. 在Action中 ...

  4. .net core web api 获取request body的纯文本

    本文代码 https://github.com/wuhaibo/readPlainTextDotNetCoreWepApi 总有些时候我们希望获得Request body 的纯文本 那么怎么做呢?很简 ...

  5. springMVC 中几种获取request和response的方式

    1.最简单方式:参数 例如: @RequestMapping("/test") @ResponseBody public void saveTest(HttpServletRequ ...

  6. 在springMVC的controller中获取request,response对象的一个方法

    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttr ...

  7. ASP.NET Core Web APi获取原始请求内容

    前言 我们讲过ASP.NET Core Web APi路由绑定,本节我们来讲讲如何获取客户端请求过来的内容. ASP.NET Core Web APi捕获Request.Body内容 [HttpPos ...

  8. RequestContextHolder 很方便的获取 request

    在 Spring boot web 中我们可以通过 RequestContextHolder 很方便的获取 request. ServletRequestAttributes requestAttri ...

  9. jeecg中的一个上下文工具类获取request,session

    通过调用其中的方法可以获取到request和session,调用方式如下: HttpServletRequest request = ContextHolderUtils.getRequest();H ...

随机推荐

  1. 【在 Nervos CKB 上做开发】Nervos CKB 脚本编程简介[5]:调试 debug

    作者:Xuejie 原文链接:https://xuejie.space/2019_10_18_introduction_to_ckb_script_programming_debugging/ Ner ...

  2. laravel hash密码生成和密码验证

    在laravel中 登录表单中的密码是用hash来生成的. 在生成密码需要用到 laravel框架中的方法(都是laravel封装好了的) bcrypt($password)方法,直接将获取到的pas ...

  3. 好用的数据库字典查看工具SQLToolbelt

    工作中经常为诸多的陌生或没有任何表或者字段说明或者文档庞大数据库和数据库表所烦恼,有以下场景: 1.新进入一家公司,开始接触新的项目,领导给你一大堆文档,在不了解具体逻辑的情况下,除了项目的结构,能让 ...

  4. .net代码混淆

    本人主要记录一下学习心得,.net关于代码混淆的知识 1.代码混淆的原理,转载链接 2.代码混淆工具,ConfuserEx的使用,转载地址

  5. docker学习之路-build asp.net core 2.2产生 warning MSB3245: Could not resolve this reference.错误的解决办法

    在docker build的时候有时我们可以直接使用dotnet publish来发布,但是如果用docker构建镜像的时候却会出现下面的错误: 解决办法:https://stackoverflow. ...

  6. Golang逃逸分析

    Golang逃逸分析 介绍逃逸分析的概念,go怎么开启逃逸分析的log. 以下资料来自互联网,有错误之处,请一定告之. sheepbao 2017.06.10 什么是逃逸分析 wiki上的定义 In ...

  7. Kruskal算法&Prim算法

    最小生成树是什么? Kruskal算法 图文转载自a2392008643的博客 此算法可以称为"加边法",初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最 ...

  8. 【转载】UiPath,UiPath教程,UiPath视频教程 RPA

    第一课-UiPath简介 第二课-变量和数据类型第1部分-基础讲解 第二课-变量和数据类型第2部分-实例讲解 第二课-流程控制第1部分-ifelse语句讲解 第二课-流程控制第3部分-高级流程控制语句 ...

  9. 为什么K8s会成为主流?

    容器技术和K8s是云原生概念的核心和基础.云计算诞生已有超过10年,但云计算时代的应用到底该是什么样子,一直没人能说清楚,也没人能确定云计算的基础架构将会如何发展.在K8s出现之前,没人设想过会有一个 ...

  10. 【转载】 使用宝塔Linux面板功能查看服务器内存使用情况

    运维过阿里云服务器或者腾讯云服务器的运维人员都知道,针对占用内存比较高的应用或者服务等,我们需要时刻关注服务器的内存使用率,是否存在内存瓶颈等情况的出现.阿里云和腾讯云官方后台界面的监控数据页面也有相 ...