.NET Web API之filter ActionFilterAttribute 过滤器使用

来源:互联网 发布:国内源码交易平台 编辑:程序博客网 时间:2024/06/08 09:32

贴图 
这里写图片描述 




知乎:显著提升程序员身心健康和工作效率的装备有哪些?

  1. 笔记本: 
    1.银河舰队 PAVILION 15-bc011TX光暗影精灵2 
    2.顽石 —FL5900U7500超薄i7(性价比最高) 

  2. 键盘: 
    1.机械键盘:FILCO 圣手 87键 红轴(日),樱桃(Cherry)G80-3000 茶轴 
    (德),DUCKY 
    2087S(台) 
    2.静电容:HHKB(日) 
    3.情怀插入:小黑USB键盘 ThinkPad USB Track Point 键盘 0B47082 

  3. 显示器:Eizo,戴尔,三星,明基,22寸以上(AOC C3208VW8 32英寸曲屏) 

  4. PC配置:i7,16G,SSD,双显示器 

  5. 电脑椅:Aeron Chair(个人经济承受能力下,最贵的) 

  6. 萌妹纸一枚(多多益善,不过太多小心受用不起) 

  1. IDE:

    1.Win(Visual Studio)2.Linux(Vim,其他真的还有必要说吗?)3.Mac(Xcode,CodeRunner,SnippetsLab)4.跨平台(Pycharm,UltraEdit,Eclipse,Source Insight,Codeblocks)5.插件(Visual Assist X,Pydev)
  2. 耳机: 
    1.听音乐:AKG Q460 
    2.玩游戏:赛睿西伯利亚 v1,v2

贴图 
这里写图片描述 


(一)、

环境说明:如果你是.NET Framework 4.0,vs2010

需要安装:Visual Studio Async CTP 

安装地址:http://www.microsoft.com/en-us/download/details.aspx?id=9983

序列化需要引用:System.Web.Extensions.dll


(二)、

新建类继承ActionFilterAttribute

 public class ActionFilter : ActionFilterAttribute    {        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)        {            base.OnActionExecuting(actionContext);            //获取请求消息提数据            Stream stream = actionContext.Request.Content.ReadAsStreamAsync().Result;            Encoding encoding = Encoding.UTF8;            stream.Position = 0;            string responseData = "";            using (StreamReader reader = new StreamReader(stream, encoding))            {                responseData = reader.ReadToEnd().ToString();            }            //反序列化进行处理            var serialize = new JavaScriptSerializer();            var obj = serialize.Deserialize<RequestDTO>(responseData);            //在action执行前终止请求时,应该使用填充方法Response,将不返回action方法体。            if (obj == null)                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, obj);            if (string.IsNullOrEmpty(obj.PhoneType) || string.IsNullOrEmpty(obj.PhoneVersion)                || string.IsNullOrEmpty(obj.PhoneID) || obj.StartCity < 1)            {                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, obj);            }        }    }

(三)、

在api控制器中的action方法上加上[过滤器类]: 例如:  [Uzai.Mobile.Filter.ActionFilter]

 public class Mobile450Controller : ApiController    {        private DoWork450Invoke _DoWork = new DoWork450Invoke();              [Uzai.Mobile.Filter.ActionFilter]        [HttpPost]        public RepProductTopicsList GetRecmdProductTopicsList(ReqProductTopicsList reqDTO)        {            return _DoWork.GetRecmdProductTopicsList(reqDTO);        }           }


web api资料太少了,慢慢摸索来的结果。参考:http://www.2cto.com/kf/201312/268995.html


—————————web api 开发之 filter————————————

1、使用filter之前应该知道的(不知道也无所谓,哈哈!)
 
  谈到filter 不得不先了解下aop(Aspect Oriented Programming)面向切面的编程。(度娘上关于aop一大堆我就不在这废话了)
 
  下面是个人理解对aop理解(不要板砖): 以前面向过程的编程,某个功能都编写成函数,在需要的时候调用。而面向对象中的编码和设计中,在类中的某个点(或者说是一个横向的切面)去实现一个功能的时候,大家也想实面向过程编码中那样简单的调用(当然不是这么简答,就是打个比方),把实例化类等繁琐的工作交给了系统去做,哈哈aop就出现了!
 
  web api 提供两种过滤器的基本类型 :
 
  1)actionfilterattribute
 
  2)exceptionfilterattribute
 
  两个类都是抽象类,actionfilter主要实现执行请求方法体之前(覆盖基类方法OnActionExecuting),和之后的事件处理(覆盖基类方法OnActionExecuted)。 exceptionfilter主要实现触发异常方法(覆盖基类方法OnException)。
 
    过滤器在实际项目中都是经常会使用到,例如日志、安全验证、全局错误处理等等。
 
2、实际使用中遇到的问题
 
   1)问题一  filter触发不了
 
   写了一个filter的例子,继承actionfilterattribute,死活触发不了!呵呵,搞了半天后来才搞明白,filter 继承了mvc4的。
 
   原来webapi 在system.web.http命名空间下,mvc在System.web.mvc下,两个空间都有filter,不知道怎么搞得,继承mvc的了,呵呵!
 
   2)问题二 在action执行前取数据,如果有二个filter,第二个取不到请求消息体数据
 
   需求是这 样的要写二个过滤器,都应用在同一个方法上,第一个取请求http消息体正常,但是第二个再取就是空了?
 
action
 
 
        [FilterAttribute1]
        [FilterAttribute2]
        public MessageResponse Post(MessageRequest messagerequest)
        {
            //方法体信息
            ................
        }
 
 
filter
 
 
        //处理功能1
        public class FilterAttribute1 : ActionFilterAttribute
        {
            public async override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
            {
                base.OnActionExecuting(actionContext);
                //获取请求消息提数据
                Stream stream = await actionContext.Request.Content.ReadAsStreamAsync();
                Encoding encoding = Encoding.UTF8;
                stream.Position = 0;
                string responseData = "";
                using (StreamReader reader = new StreamReader(stream, encoding))
                {
                    responseData = reader.ReadToEnd().ToString();
                }
 
                //然后反序列化进行处理
                ..................
            }
            public async override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
            {
                base.OnActionExecuted(actionExecutedContext);
                //获取返回消息数据
                var response =
                        await
                        actionExecutedContext.Response.Content.ReadAsAsync(
                            actionExecutedContext.ActionContext.ActionDescriptor.ReturnType);
            }
 
       }
        //处理功能2
        public class FilterAttribute2 : ActionFilterAttribute
        {
            public async override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
            {
                base.OnActionExecuting(actionContext);
                //获取请求消息提数据
                Stream stream = await actionContext.Request.Content.ReadAsStreamAsync();
                //在这stream值是空的。
                Encoding encoding = Encoding.UTF8;
                stream.Position = 0;
                string responseData = "";
                using (StreamReader reader = new StreamReader(stream, encoding))
                {
                    responseData = reader.ReadToEnd().ToString();
                }
 
                //然后反序列化进行处理
                ..................
                
            }
            
        }
 
 始终没有想没那个白,为什么第二个filter取不到?请教前辈有的说当第一个stream 取完,流关闭了,所以取不到,有的说第一个取后,加锁了.....等等,到现在我还是没有搞明白到底是为什么,还好找到解决方法,代码总算是可以王下写。换了一种思路,从actionContext中找到了取得输入参数的方法,正好是所需要的请求消息数据。实现如下
 
 
 
//修改后,后边filter数据照常取出,问题解决
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            base.OnActionExecuting(actionContext);
            string responsemessagebody = "";
 
            Dictionary<string, object> actionargument = actionContext.ActionArguments;
 
 
 
 
            foreach (KeyValuePair<string, object> arg in actionargument )
            {
                //每天action的消息体不同可以tostring,然后处理
                responsemessagebody += arg.ToString();
                //请求消息体相同
                可以直接使用
                    (typeobject)arg 直接使用
            }
            ...........
 
 
}
 
 
3、总结一下还有些需要注意
 
  1)在action执行前终止请求时,应该使用填充方法Response,将不返回action方法体。
 
例如:当验证判断不合法时,返回错误信息而不再继续执行action代码。
 
代码如下:
 
  actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, object(返回对象));
object将会被系统直接按默认方式,序列化。
   
  2)在action,或filter中取得当前路径(物理/其他信息)
    使用 HttpRuntime 对象
 
web api 的简单例子,网上不少,但是涉及深入开发和实际应用的少之又少,这方面的书籍好像也没有找到,解决问题只能靠msdn,枯燥呀!希望能和大家交流,共同进步。


贴图 
这里写图片描述 




知乎:显著提升程序员身心健康和工作效率的装备有哪些?

  1. 笔记本: 
    1.银河舰队 PAVILION 15-bc011TX光暗影精灵2 
    2.顽石 —FL5900U7500超薄i7(性价比最高) 

  2. 键盘: 
    1.机械键盘:FILCO 圣手 87键 红轴(日),樱桃(Cherry)G80-3000 茶轴 
    (德),DUCKY 
    2087S(台) 
    2.静电容:HHKB(日) 
    3.情怀插入:小黑USB键盘 ThinkPad USB Track Point 键盘 0B47082 

  3. 显示器:Eizo,戴尔,三星,明基,22寸以上(AOC C3208VW8 32英寸曲屏) 

  4. PC配置:i7,16G,SSD,双显示器 

  5. 电脑椅:Aeron Chair(个人经济承受能力下,最贵的) 

  6. 萌妹纸一枚(多多益善,不过太多小心受用不起) 

  1. IDE:

    1.Win(Visual Studio)2.Linux(Vim,其他真的还有必要说吗?)3.Mac(Xcode,CodeRunner,SnippetsLab)4.跨平台(Pycharm,UltraEdit,Eclipse,Source Insight,Codeblocks)5.插件(Visual Assist X,Pydev)
  2. 耳机: 
    1.听音乐:AKG Q460 
    2.玩游戏:赛睿西伯利亚 v1,v2

贴图 
这里写图片描述 


1 0
原创粉丝点击