.NET mvc 中ActionFilter特性可以再在一个Request进入Controller之前,直到View的数据绑定之前都可以触发,它主要包含以下四个方法:

OnActionExecuted

Called by the ASP.NET   MVC framework after the action method executes. (request进入controller,并且执行结束时触发,)

OnActionExecuting

Called by the ASP.NET MVC framework before the action method executes. (request尚未进入controller触发,)

OnResultExecuted

Called by the ASP.NET   MVC framework after the action result executes. . (action的 方法执行完毕,并且结果执行完毕(数据绑定结束) 触发 )

OnResultExecuting

Called by the ASP.NET   MVC framework before the action result executes. . (action的 方法执行完毕,但是结果执行之前(数据绑定结束) 触发  )

详细MVC ActionFilter的资料请参照:http://msdn.microsoft.com/zh-cn/library/system.web.mvc.actionfilterattribute(v=vs.108).aspx.

利用ActionFilter其中的四个方法,我们可以完整的记录下整个网站进入Action之前传入的参数,以及Action执行之后返回的 ViewModel。

以下是具体的实现方式:

1.在MVC项目中添加一个ActionFilter特性。

/// <summary>

/// the action filter to trace frontent request and   response.

/// </summary>

public class LoggingAttribute   : ActionFilterAttribute

{

/// <summary>

/// Called when [action executing].

/// </summary>

/// <param   name="filterContext">The filter   context.</param>

public   override void   OnActionExecuting(ActionExecutingContext   filterContext)

{

if   (filterContext.ActionParameters != null)

{

//   LoggingAttribute 只会拥有一个实例,并且运用于所有的Cotrollers,所以我们必须保证每一次Request只会记录自己的数据

filterContext.HttpContext.Items[HttpContextConstants.RequestData]   = filterContext.ActionParameters;

filterContext.HttpContext.Items[HttpContextConstants.Stopwatch]   = Stopwatch.StartNew();

}

base.OnActionExecuting(filterContext);

}

/// <summary>

/// Called when [action executed].

/// </summary>

/// <param   name="filterContext">The filter   context.</param>

public   override void   OnActionExecuted(ActionExecutedContext   filterContext)

{

string   methodName = filterContext.ActionDescriptor.ActionName;

string   conrtrollerName =   filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;

object   response = null;

if   (filterContext != null &&   filterContext.Result != null)

{

var   result = filterContext.Result;

//.net framework 提供了 7种 ActionResult ,这里需要看项目的设计,我们只需要分析各自项目会运用到哪些ActionResult,并且拿到相应的Model或者Data(如果没有返回值就不需要,Response就是null)

if   (result is ViewResultBase)

{

if ((result as ViewResultBase).Model   != null)

{

response = (result as ViewResultBase).Model;

}

}

else   if (result is   JsonResult)

{

if   ((result as JsonResult).Data   != null)

{

response = (result as JsonResult).Data;

}

}

}

TraceFrontendRequest(conrtrollerName, methodName, response);

base.OnActionExecuted(filterContext);

}

/// <summary>

/// Traces the frontend request.

/// </summary>

/// <param name="controllerName">Name of the controller.</param>

/// <param   name="methodName">Name of the   method.</param>

/// <param   name="response">The response.</param>

private   void TraceFrontendRequest(string controllerName, string   methodName, object response)

{

try

{

var   request = HttpContext.Current.Items[HttpContextConstants.RequestData];

var   stopWatch = HttpContext.Current.Items[HttpContextConstants.Stopwatch] as Stopwatch;

long   elapse = null == stopWatch ? 0 :   stopWatch.ElapsedMilliseconds;

string   category = string.Format("{0}/{1}", controllerName,   methodName);

LogManager.TraceFrontendRequest(

category,

request,

response,

controllerName,

methodName,

elapse);

}

catch   (Exception ex)

{

//log the error message

}

}

}

2. 序列化Response和Request

.net framework 提供了很多的序列化方法,比如XmlSerializer, JavaScriptSerializer, DataContractSerializer, DataContractJsonSerializer.

  1. XML 序列化是将对象的公共属性   (Property) 和字段转换为序列格式(这里是指 XML)以便存储或传输的过程。反序列化则是从 XML 输出中重新创建原始状态的对象。详细参考:http://msdn.microsoft.com/zh-cn/library/system.xml.serialization.xmlserializer(v=VS.80).aspx
  2. JavaScriptSerializer序列化为启用 AFAX 的应用程序提供序列化和反序列化功能。(序列化的结果格式和Json对象一样,难以阅读)详细参考:http://msdn.microsoft.com/zh-cn/library/vstudio/system.web.script.serialization.javascriptserializer(v=vs.90).aspx
  3. DataContractSerializer序列化使用提供的数据协定,将类型实例序列化和反序列化为   XML 流或文档(专为WCF服务)。详细参考:http://msdn.microsoft.com/zh-cn/library/vstudio/system.runtime.serialization.datacontractserializer.aspx。
  4. DataContractJsonSerializer将对象序列化为 JavaScript 对象表示法 (JSON),并将 JSON 数据反序列化为对象。详细参考:http://msdn.microsoft.com/zh-cn/library/vstudio/system.runtime.serialization.json.datacontractjsonserializer.aspx
 
 

2.1序列化方法的选定:

在ActionFilterAttribute  OnActionExecuting方法中,我们可以ActionExecutingContext.ActionParameters,以下是ActionExecutingContext的结构:

namespace   System.Web.Mvc

{

public class ActionExecutingContext   : ControllerContext

{

public   ActionExecutingContext();

public   ActionExecutingContext(ControllerContext   controllerContext, ActionDescriptor   actionDescriptor, IDictionary<string, object>   actionParameters);

public   virtual ActionDescriptor   ActionDescriptor { get; set; }

public   virtual IDictionary<string, object>   ActionParameters { get; set; }

public   ActionResult Result { get; set; }

}

}

Xml序列化不支持IDictionary类型,JavaScriptSerializer没有可读性,DataContractSerializer序列缺少必要的Contract,所以我们只能采用DataContractJsonSerializer。

2.2DataContractJsonSerializer使用的条件。

1)  DataContractJsonSerialier在序列化的过程,必须知道对象的具体类型, 当序列化对象派生于某基类时,我们需要使用KnownTypes特性。

2)  在Controller中,如果返回的是Json对象,我们不能返回一个匿名类的Json对象(任何序列化方法都无法有效识别匿名类的类型,因此无法确定序列化的结构)。比如:

public JsonResult GetSubscriptions()

{

int   total = 0;

return   new JsonResult()

{

Data = new

{

Rows = …,

TotalSize = total,

PageNum = ….

PageSize = ….

}

};

}

3. DataContractJsonSerializer 实现代码

由于ViewModel可能作为被返回的ViewModel,也可能是页面 Post回来的RequestParameters. 所以我们可以设计一个BaseModel类,用以实现KnownType特性。

1) BaseModel的实现

[KnownType("GetKnownTypes")]  // for   serialization

public class BaseModel

{

/// <summary>

/// Gets or sets the known types.

/// </summary>

/// <value>

/// The known types.

/// </value>

private   static List<Type> KnownTypes { get;   set; }

/// <summary>

/// Gets the known types.

/// </summary>

/// <returns></returns>

public   static List<Type> GetKnownTypes()

{

return   KnownTypes;

}

/// <summary>

/// Initializes the <see   cref="BaseModel"/> class.

/// </summary>

static   BaseModel()

{

//只需要执行一次,运用反射,获取到所有继承与BaseModel的类的类型。

KnownTypes = new List<Type>();

try

{

foreach   (Type type in   Assembly.GetExecutingAssembly().GetTypes())

{

if   (!type.IsAbstract && type.IsSubclassOf(typeof(BaseModel)))

{

KnownTypes.Add(type);

}

}

}

catch   (Exception ex)

{

//log error message

}

}

}

/// <summary>

/// Subscription Details View Model

/// </summary>

public class SubscriptionDetailsViewModel   : BaseModel

{

}

2) DataContractJsonSerializer方法

/// <summary>

/// Datas the contract serialize.

/// </summary>

/// <param   name="obj">The obj.</param>

/// <returns></returns>

public   static string   DataContractSerialize(object obj)

{

if   (null == obj)

{

return   string.Empty;

}

Type   objectType = obj.GetType();

//In   case of primitive type or string type, just return the ToString value

if   (objectType.IsPrimitive || objectType == typeof(string) || obj is Exception)

{

return   obj.ToString();

}

//otherwise,   return the xml serialization of the object

string   output = string.Empty;

try

{

DataContractSerializer   serializer = new DataContractSerializer(objectType);

using   (StringWriter sw = new StringWriter())

{

using   (XmlTextWriter writer = new XmlTextWriter(sw)   { Formatting = Formatting.Indented })

{

serializer.WriteObject(writer, obj);

}

output =   sw.GetStringBuilder().ToString();

}

}

catch   (Exception e)

{

//log error message

}

return   output;

}

转载于:https://www.cnblogs.com/murder/archive/2012/11/28/Muder.html

.NET利用ActionFilter特性记录日志或者运行性能计数器。(log trace or perform perfcounter by actionFilter attribute)...相关推荐

  1. mvc4 利用filters特性来 实现自己的权限验证 之二

    刚开始摸索C# MVC,也只是按图索骥,对C#的特性不是很懂,耐心看完相关文章,对特性的使用有了进一步理解. 1.特性类的命名规范:特性也是一个类,必须继承于System.Attribute类,命名规 ...

  2. 寻宝游戏 - 利用iBeacon特性设计的iOS线下寻宝游戏 - 物联网小游戏

    寻宝游戏 - 利用iBeacon特性设计的iOS线下寻宝游戏 作者简介 科科香,程序员 方向:IoT,方案集成,喜好各种新鲜东东 转载请注明出处 iBeacon简介 iBeacon(下面简称Beaco ...

  3. 利用多态特性,创建一个手机类Phones,定义打电话的方式call,创建三个子类,并在各自的方法中重写方法,编写程序入口main()方法,实现多种手机打电话...

    |--需求说明 利用多态特性,创建一个手机类Phones,定义打电话的方式call,创建三个子类,并在各自的方法中重写方法,编写程序入口main()方法,实现两种手机打电话 |--解题思路 采用简单工 ...

  4. 利用多态特性,编程创建一个手机类Phones,定义打电话方法call()。创建两个子类:苹果手机类IPhone和安卓手机类APhone,并在各自类中重写方法call(),编写程序入口main()方法

    利用多态特性,编程创建一个手机类Phones,定义打电话方法call().创建两个子类:苹果手机类IPhone和安卓手机类APhone,并在各自类中重写方法call(),编写程序入口main()方法, ...

  5. 利用jdk自带的运行监控工具JConsole观察分析Java程序的运行 Jtop

    利用jdk自带的运行监控工具JConsole观察分析Java程序的运行 原文链接 一.JConsole是什么 从Java 5开始 引入了 JConsole.JConsole 是一个内置 Java 性能 ...

  6. 利用PHP安装windows自动运行的服务,PHP程序可以实现长时间、自动运行、定时更新功能,直接可以用在项目中的类源代码...

    为什么80%的码农都做不了架构师?>>>    什么 windows服务 ? Windows 服务(即,以前的 NT 服务)使您能够创建在它们自己的 Windows 会话中可长时间运 ...

  7. 利用css特性布局页面制作京东特价框

    布局技巧:利用css特性去制作京东价格图框: 类似步骤: 1.首先制作一个四边形的样式,对高度和宽度进行设置,两者设置为0px 2.原来制作一个四边形里面的一个三角形部分采取的是对颜色设置transp ...

  8. css3三角形兼容_利用css3特性写出三角形(兼容IE浏览器)

    利用CSS写出三角形的效果 效果如图: 代码如下: .triangle-up { width:0px; height:0px; border-left:10px solid transparent; ...

  9. javascript 算法相关,如何利用指针特性求数组并集与交集

    如何利用指针特性求数组并集与交集 javascript计算数组交集,并集,网上有很多,有些书也有介绍, 很多都是写一个set类,再添加一些方法,本质上都是利用了多次循环 我在写这个的时候,也是被别人问 ...

  10. Kali运行smod框架报错‘Conf‘ object has no attribute ‘use_dnet‘

    Kali运行smod框架报错'Conf' object has no attribute 'use_dnet' 报错信息如下 解决方法 报错信息如下 // smod运行报错详细内容 Traceback ...

最新文章

  1. JS DATE对象详解
  2. 生产者消费者模式 php 【转】
  3. Java中常见的十八种异常!
  4. 遨游3.0 RC 版公布
  5. DB2 SQL性能调优秘笈pdf
  6. zemax验证高斯公式_ZEMAX 实验讲义
  7. c语言学习-求一元二次方程的根
  8. 在Java中==的一个坑
  9. 企业收集客户信息有哪些方式?
  10. c# 超时时间已到.在操作完成之前超时时间已过或服务器未响应,超时过期了。在操作完成或服务器没有响应之前经过的超时时间。声明已被终止...
  11. 前端工程化:vue代码检查工具vetur
  12. python matting后如何设置透明背景
  13. linux xen 管理,ARM平台上运行Xen 可同时管理linux和VxWorks
  14. 用word字体转换来代替手写作业--最详细
  15. ZYNQ学习之旅--PS_AXI_VDMA(利用VDMA实现将PS端的数据显示在PL端的HDMI上)
  16. DS18B20温度采集报警系统,原理及汇编、C语言实现
  17. C#输出Word文档
  18. 高仿网易云音乐一(可扫描本地音乐播放)
  19. CTF-RSA1(已知p、q、dp、dq、c)
  20. 剑网3指尖江湖开局门派选TA最好 叉叉助手伴你快意江湖

热门文章

  1. MyBatis实现一对一,一对多关联查询
  2. excel筛选,排序
  3. 威联通 ※ 群晖 虚拟机性能对比 我可能要碰瓷 eSir
  4. 安装光盘并重新启动计算机戴尔,戴尔电脑怎么设置光盘启动
  5. 华为路由器基本使用命令
  6. ERR Slot 741 is already busy (Redis::CommandError)
  7. 天线发射功率计算公式_天线增益的定义/计算公式/发射功率
  8. 推荐25个值得收藏的前端开源Awesome项目
  9. C# datagridview / datatable 导出带表头的excel的数据
  10. 2022数字化工地智慧防疫系统助力工地疫情防控实现人员、施工安全闭环管理