zoukankan      html  css  js  c++  java
  • 使用特性(Attribute)记录WebService的请求记录

    背景:

      项目架构是webservice做服务端,通过json来传递数据。前端有安卓、IOS、PHP几个团队。前端团队经常反馈遇到服务调用失败的情况,但是我们查看代码发现服务并没什么问题,所以经常会发生扯皮的情况,基于这个前提下,做一个记录前端请求的模块,记录前端请求的参数是否正确。

    需求:

      记录某些重要的请求的WebMethod及其请求的信息。

    方案:

      1.直接在每个WebMethod里修改,添加记录日志的代码

      2.重写IHttpModule记录请求,自定义HttpApplication的BeginRequest事件记录日志。

      3.添加全局应用程序记录请求,在Application_BeginRequest里记录日志。

      4.使用特性,新增中间层继承ContextBoundObject,通过传递上下文来记录日志。

    分析:

      1.第1种需要改动现有的WebMethod,破坏原有结构。

      2.第2种和第3种其实是一样的,都可以接收到所有的请求。

      3.第4种非常灵活,可以在想要的WebMethod上添加,且不会修改到原有的逻辑。但是新增中间层传递上下文无疑是增加了结构发复杂性,考虑到现有项目已经比较大了,不想牵一发而动全身。

    选择:

      先定义一个用于标记是否需要写日志的特性,重写IHttpMoudule,拿到请求的文件及方法,通过反射判断该方法是否包含需要写日志的特性。


    实现:

    新增一个类RequestLogAttribute.cs继承Attribute,并且设置应用级别为方法。

        [AttributeUsage(AttributeTargets.Method)]
        public class RequestLogAttribute : Attribute { }


    新增一个类RequestLoggerHttpModule.cs继承IHttpModule,并实现Init方法。在Init方法中添加自定义事件HttpApplication.BeginRequest,可以拿到我们熟悉的HttpRequest、HttpContext、HttpResponse。

         public class RequestLoggerHttpModule : IHttpModule
        {
            public void Init(HttpApplication context)
            {
                context.BeginRequest += new EventHandler(Application_BeginRequest);
            }
            
             void Application_BeginRequest(object sender, EventArgs e)
            {
                HttpApplication application = sender as HttpApplication;
                HttpContext context = application.Context;
                HttpRequest request = application.Request;
                HttpResponse response = application.Response;
    
            }
    
             public void Dispose(){}
        }

    同时,在Web.Config里添加节点

    <system.webServer>
        <modules>
          <add name="RequestLoggerHttpModule" type="命名空间.RequestLoggerHttpModule,程序集名"></add>
        </modules>
      </system.webServer>

    有了HttpRequest之后,用反射拿到请求的方法,并且判断是否不是存在我们定义的特性。

            #region 是否存在记录日志的特性
            /// <summary>
            /// 是否存在记录日志的特性
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            bool LogAttribute(HttpRequest request)
            {
                string extension = request.CurrentExecutionFilePathExtension;
                if (string.IsNullOrEmpty(extension)) return false;
                string filePath = request.FilePath.Replace(extension, string.Empty);
                int last = filePath.LastIndexOf('/');//取最后一个/
                filePath = filePath.Substring(last, filePath.Length - last);
    
                string className = filePath.Replace("/", string.Empty);
                string methodName = request.PathInfo.Replace("/", string.Empty);
                Type t = Type.GetType(className);
    
                if (t == null || string.IsNullOrEmpty(methodName)) return false;
    
                MethodInfo method = t.GetMethod(methodName);
    
                if (method == null) return false;
    
                object[] attributes = method.GetCustomAttributes(typeof(RequestLogAttribute), false);
                if (attributes == null || attributes.Length <= 0) return false;
    
                return true;
            }
            #endregion

    所有请求的信息都包含在HttpRequest中,这个不再赘述。如有疑问可以参考:HttpRequest

    使用方法也很简单

            [WebMethod]
            [RequestLog]
            public void Test()
            {
            }


  • 相关阅读:
    简析IGRP
    unicode字符集查找
    中国移动建成全球最大软交换网络 适合向3G过渡
    寻找端口与进程的关联
    framerelay
    网络工程师的素质
    E1通信的基础知识
    Indy UDP端口冲突解决
    『软考』接入网的分类
    随便写写。。
  • 原文地址:https://www.cnblogs.com/wugang/p/14232327.html
Copyright © 2011-2022 走看看