博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何在WebApi中使用过滤器实现面向切面编程(AOP)
阅读量:5463 次
发布时间:2019-06-15

本文共 7873 字,大约阅读时间需要 26 分钟。

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

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

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

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

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

 

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

 在表单对象FromOrderInfo实体类里面有ValidateMobile和ValidateMaxLength验证类

接下来我们需要编写自定义ValidateMobile和ValidateMaxLength验证类

自定义验证如下:

1 ///  2     /// 验证字符长度是否超过指定长度 3     ///  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 /// 31    /// 验证手机号32    /// 33    public class ValidateMobileAttribute : ValidationAttribute34     {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     }
View Code

 

表单参数和自定义验证类完成了,接下来就是用户提交订单,就需要请求API接口。 订单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
("json").Response("下单成功"); 7 return challengeMessage; 8 9 }10 11 ///
12 /// Post表单参数13 /// 14 public class FromInfo15 {16 ///
17 /// Json数据对象18 /// 19 public string JsonFormat { get; set; }20 }
View Code

 

因API接口中POST请求只能用[FromBody]来包含,所以我们需要把表单参数转换成Json格式的字符串,用JsonFormat 来接收。。。

 接下来就是编写CHKFormInput过滤器,在进入之前Action之前对表单参数进行拦截验证。

定义过滤器代码:
1 ///  2     /// 验证表单参数 3     ///  4 public class CHKFormInput : ActionFilterAttribute 5     { 6         private Type _type; 7         ///  8         /// 构造函数 9         /// 10         /// 表单参数验证对象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             try24             {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
(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
("json").Response(errorMsgConvertjson);53 actionContext.Response = challengeMessage;54 }55 56 }57 58 }59 catch (Exception ex)60 {61 }62 finally63 {64 }65 base.OnActionExecuting(actionContext);66 #endregion67 }68 }
View Code

 

定义了过滤器后,我们如何把截取到的FromOrderInfo表单参数来进行验证呢?

  然后我们还需要继续编写一个类来执行附加在实体属性的验证规则

实体对像属性验证类:
1 ///  2     /// 利用特性验证实体对象参数合法性 3     ///  4     public class TryValidateModelTool : ApiController 5     { 6         ///  7         /// 利用特性验证实体对象参数合法性 8         ///  9         /// 对象10         /// 错误信息11         /// 
12 public bool TryValidateModel(object model, ref string errorMsg)13 {14 return TryValidateModel(model, null /* prefix */, ref errorMsg);15 }16 17 18 19 20 /// 21 /// 利用特性验证实体对象参数合法性22 /// 23 /// 对象24 /// 错误信息25 ///
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
errorMsgList = new List
();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 }
View Code

 

 

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

感谢您的阅读!

 

转载于:https://www.cnblogs.com/dzycwy/p/5336181.html

你可能感兴趣的文章
Javascript编码风格
查看>>
django
查看>>
ASP.NET MVC 3 新特性
查看>>
vue报错信息
查看>>
布林带
查看>>
数据平滑
查看>>
奇异值分解
查看>>
快速傅里叶变换模块(fft)
查看>>
随机数模块(random)
查看>>
杂项功能(排序/插值/图像/金融相关)
查看>>
pandas核心
查看>>
线性回归
查看>>
机器学习学习索引
查看>>
多项式回归
查看>>
Python-字符串
查看>>
MySQL8.0安装以及介绍(二进制)
查看>>
MySQL权限系统
查看>>
Python-集合
查看>>
转:标签中的href如何调用js
查看>>
CrawlSpiders简介
查看>>