WebApi中过滤器的AOP实现方式

说到AOP编程,可能大部分人是即熟悉又显得陌生。

AOP的作用就是横切关注点,然后将分离后的关注点以面的形式来呈现,这是概念性的说法,举个列子来说明吧。

比如说有个API接口处理场景是提交订单,在我们提交订单的时候,首先客户端要对用户提交的数据进行合法性验证,验证通过后,数据发送到服务端,因客户端一切操作都是不可信的,必然服务端在录入订单信息之前也需要对数据合法性进行验证。

针对上述问题我们可以这样子来编码

首先定义订单表单参数实体对象:

 1 /// <summary>
 2     /// Post表单参数
 3     /// </summary>
 4     public class FromOrderInfo
 5     {
 6         /// <summary>
 7         /// 商品名称
 8         /// </summary>
 9         public string ShopName { get; set; }
10         /// <summary>
11         /// 手机号
12         /// </summary>
13         [ValidateMobile(ErrorMessage = "请输入正确格式的手机号")]//自定义验证规则
14         public string Mobile { get; set; }
15         /// <summary>
16         /// Address
17         /// </summary>
18         [ValidateMaxLength(20,ErrorMessage = "Address字符超过指定长度")]
19         public string Address { get; set; }
20     }
 

自定义验证如下:

 1 /// <summary>
 2     /// 验证字符长度是否超过指定长度
 3     /// </summary>
 4     public class ValidateMaxLengthAttribute : ValidationAttribute
 5     {
 6         private readonly int MaxLength;
 7
 8         public ValidateMaxLengthAttribute(int maxLength)
 9             : base("{0}的字符太多了!")
10         {
11             MaxLength = maxLength;
12         }
13
14         protected override ValidationResult IsValid(object value, ValidationContext validationContext)
15         {
16             if (value != null)
17             {
18                 string content = value.ToString();
19                 int leng = StringTool.GetStringLength(content);
20                 if (leng > MaxLength)
21                 {
22                     string errorMessage = FormatErrorMessage(validationContext.DisplayName);
23                     return new ValidationResult(errorMessage);
24                 }
25             }
26             return ValidationResult.Success;
27         }
28     }
29
30 /// <summary>
31    /// 验证手机号
32    /// </summary>
33    public class ValidateMobileAttribute : ValidationAttribute
34     {
35        public ValidateMobileAttribute()
36             : base("{0}应输入11位手机号!")
37         {
38         }
39        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
40        {
41            if (value != null)
42            {
43                string content = value.ToString();
44                if (!RegexTool.IsMobile(content))
45                {
46                    string errorMessage = FormatErrorMessage(validationContext.DisplayName);
47                    return new ValidationResult(errorMessage);
48                }
49            }
50            return ValidationResult.Success;
51        }
52     }

订单API接口:

 1  [CHKFormInput(typeof(FromOrderInfo))]
 2         public HttpResponseMessage TestOrder([FromBody] FromInfo info)
 3         {
 4             var challengeMessage = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.OK);
 5
 6             challengeMessage = new ResponseMessage<string>("json").Response("下单成功");
 7             return challengeMessage;
 8
 9         }
10
11 /// <summary>
12     /// Post表单参数
13     /// </summary>
14     public class FromInfo
15     {
16         /// <summary>
17         /// Json数据对象
18         /// </summary>
19         public string JsonFormat { get; set; }
20     }

定义过滤器:

 1 /// <summary>
 2     /// 验证表单参数
 3     /// </summary>
 4 public class CHKFormInput : ActionFilterAttribute
 5     {
 6         private Type _type;
 7         /// <summary>
 8         /// 构造函数
 9         /// </summary>
10         /// <param name="type">表单参数验证对象</param>
11         public CHKFormInput(Type type = null)
12         {
13             if (type != null)
14             {
15                 this._type = type;
16             }
17         }
18         public override void OnActionExecuting(HttpActionContext actionContext)//执行action动作所需执行的操作
19         {
20             #region 检查表单参数是否合法
21             var challengeMessage = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.OK);
22             ErrorResponse errorMsgConvertjson = new ErrorResponse();//返回错误信息string errorMsg = string.Empty;
23             try
24             {
25                 if (actionContext == null)
26                 {
27                     throw new System.Web.Http.HttpResponseException(challengeMessage);
28                 }
29                 if (ProjectRequest.IsPost())//验证是否POST请求
30                 {
31                     var task = actionContext.Request.Content.ReadAsStreamAsync();
32                     var content = string.Empty;
33                     using (System.IO.Stream sm = task.Result)
34                     {
35                         if (sm != null)
36                         {
37                             sm.Seek(0, SeekOrigin.Begin);
38                             int len = (int)sm.Length;
39                             byte[] inputByts = new byte[len];
40                             sm.Read(inputByts, 0, len);
41                             sm.Close();
42                             content = Encoding.UTF8.GetString(inputByts);
43                         }
44                     }
45                     var m = JsonTool.JsonToEntity<FromInfo>(content);
46                     var Json = Serializer.Deserialize(m.JsonFormat, _type);
47                     new TryValidateModelTool().TryValidateModel(Json, ref errorMsg);
48                     if(!string.IsNullOrEmpty(errorMsg))
49                     {
50                         errorMsgConvertjson.Message = errorMsg;
51                         errorMsgConvertjson.State = CallBackServer.InputError;
52                         challengeMessage = new ResponseMessage<ErrorResponse>("json").Response(errorMsgConvertjson);
53                         actionContext.Response = challengeMessage;
54                     }
55
56                 }
57
58             }
59             catch (Exception ex)
60             {
61             }
62             finally
63             {
64             }
65             base.OnActionExecuting(actionContext);
66             #endregion
67         }
68     }

实体对像属性验证类:

 1 /// <summary>
 2     /// 利用特性验证实体对象参数合法性
 3     /// </summary>
 4     public class TryValidateModelTool : ApiController
 5     {
 6         /// <summary>
 7         /// 利用特性验证实体对象参数合法性
 8         /// </summary>
 9         /// <param name="model">对象</param>
10         /// <param name="errorMsg">错误信息</param>
11         /// <returns></returns>
12         public bool TryValidateModel(object model, ref string errorMsg)
13         {
14             return TryValidateModel(model, null /* prefix */, ref errorMsg);
15         }
16
17
18
19
20         /// <summary>
21         /// 利用特性验证实体对象参数合法性
22         /// </summary>
23         /// <param name="model">对象</param>
24         /// <param name="errorMsg">错误信息</param>
25         /// <returns></returns>
26         public bool TryValidateModel(object model, string prefix, ref string errorMsg)
27         {
28             if (model == null)
29             {
30                 throw new ArgumentNullException("model");
31             }
32
33             ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType());
34             var t = new ModelBindingExecutionContext(new HttpContextWrapper(HttpContext.Current), new System.Web.ModelBinding.ModelStateDictionary());
35             List<string> errorMsgList = new List<string>();
36             foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(metadata, t).Validate(null))
37             {
38                 ModelState.AddModelError(validationResult.MemberName, validationResult.Message);
39                 errorMsgList.Add(validationResult.Message);
40             }
41             errorMsg = string.Join(",", errorMsgList);
42             return ModelState.IsValid;
43         }
44     }

至此整个AOP过滤器编码全部完成,在用户提交表单之前,API接口会首先进入CHKFormInput 过滤器验证参数合法性,如验证失败,将不进入提交订单的API接口

感谢您的阅读!
时间: 2024-11-08 08:14:53

WebApi中过滤器的AOP实现方式的相关文章

WebApi 中开启跨域请求方式

1.配置web.config文件 <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="*" /> <add name="Access-Control-Al

MVC与WebApi中的异常过滤器

一.MVC的异常过滤器 1.自定义MVC异常过滤器 创建一个类,继承HandleErrorAttribute即可,如果不需要作为特性使用直接实现IExceptionFilter接口即可, 注意,该接口在System.Web.Mvc 命名空间下 /// <summary> /// 自定义的MVC异常过滤器 /// 可以在Controller或Action上单独使用,也可直接注册为全局过滤器 /// </summary> publicclassMVCExceptionFilterAtt

Asp.Net WebAPI中Filter过滤器的使用以及执行顺序

转发自:http://www.cnblogs.com/UliiAn/p/5402146.html 在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想,通过Filter能统一地对一些通用逻辑进行处理,如:权限校验.参数加解密.参数校验等方面我们都可以利用这一特性进行统一处理,今天我们来介绍Filter的开发.使用以及讨论他们的执行顺序. Filter

在webapi中为Action使用dynamic参数实现Post方式调用

原文:在webapi中为Action使用dynamic参数实现Post方式调用 1.在webapi中使用controller/action/id的路径配置,打开文件[App_Start] -[WebApiConfig] config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RoutePa

OAuth在WebApi中的使用,前后台分离的调用方式

前段时间由于公司架构服务层向WebApi转换,就研究了OAuth在WebApi中的使用,这中间遇到了很多坑,在此记录一下OAuth的正确使用方式. 1.  OAuth是做什么的? 在网上浏览时,大家都见过这样的功能:网站A提供了第三方登录服务,比如使用新浪微博.QQ账户登录.用户使用第三方账户登陆后,第三方返回Token给网站A,当网站A调用第三方服务请求登录用户信息时需传递该Token给第三方,第三方才允许该服务请求.之后的每次请求无需再次认证,直接使用该Token即可.这就是OAuth的典型

webapi中使用token验证(JWT验证)

本文介绍如何在webapi中使用JWT验证 准备 安装JWT安装包 System.IdentityModel.Tokens.Jwt 你的前端api登录请求的方法,参考 axios.get("api/token?username=cuong&password=1").then(function (res) { // 返回一个token /* token示例如下 "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZ

(五).NET Core中过滤器Filter的使用介绍

知识点回顾: 前面几篇文章分别给大家介绍了 (1)Swagger的集成和用法: (2)JWT身份验证的集成和用法: (3)OOM框架AnutoMapper对象映射的用法: 今天给大家介绍过滤器Filter的基本使用: 过滤器有什么作用,在什么场景下适合用到它? 假设一个项目进展到快结束的时候,项目leader为了保证程序的稳定性和可监控和维护性要求将所有的方法加上日志,如果项目比较庞大,方法非常多,那岂不是得费很大得劲来完成这样一件事情.不过不用担心,咋们遇到的问题,伟大的语言设计者早已帮我们想

.NET Core中过滤器Filter的使用介绍

过滤器有什么作用,在什么场景下适合用到它? 假设一个项目进展到快结束的时候,项目leader为了保证程序的稳定性和可监控和维护性要求将所有的方法加上日志,如果项目比较庞大,方法非常多,那岂不是得费很大得劲来完成这样一件事情.不过不用担心,咋们遇到的问题,伟大的语言设计者早已帮我们想好了解决办法过滤器,过滤器是一种AOP(面向切面编程)技术的体现,AOP具有松耦合,易扩展,代码可复用的特点. 通常我们在这些场景下如身份验证.日志记录.异常获取等会使用到过滤器 .NET Core中的过滤器生命周期:

spring - aop 使用方式总结

方式一:接口 前置增强      MethodBeforeAdvice 后置增强      AfterReturningAdvice 异常抛出增强  ThrowsAdvice 环绕增强      MethodInterceptor 注意:还需要在applicationContext.xml文件中进行aop相关的配置 <aop:config>        <aop:pointcut expression="execution(public void *User())"