Asp.Net MVC FilterAttribute特性读取xml反序列化、NLog实战系列文章

注:如果你理解了AOP,那么看这篇文章的第三部分可能更轻松点;

如果你理解了单例模式和反射原理, 那么看这篇文章的第二部分的第二小部分可能更轻松点;

首先新建一个MVC project。

一、NLog的配置。

作者:Jarosław Kowalski <jaak@jkowalski.net>

翻译:CrazyCoder

原文:http://www.nlog-project.org/config.html

更多关于NLog的中文文章,请参考《NLog文章系列》。

(1)在当前project中引用NLog相关dll文件。

此时会发现project底下多了两个文件。可以自己新建一个Config文件夹,把这两个文件移进去。

(2)接下来就是根据自己个人需求配置NLog。

$1、到Web.Config添加以下配置。

 <configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
</configSections>
<nlog>
<include file="${basedir}/Config/NLog.config" /><!--包含文件 此处配置为前面引用NLog时添加的NLog.config文件-->
</nlog>
</configuration>

$2、一个新添加的NLog.config是没有指定"输出目标“和"规则"的,所以我们自己添加targets和rules。

 <targets>
<target name="toLogFile" xsi:type="File"
archiveAboveSize="2097152"
fileName="d:/LogFiles/NLogTest/${shortdate}.log"
archiveFileName="d:/LogFiles/NLogTest/{#}.txt"
archiveNumbering="DateAndSequence"
archiveEvery="Day"
maxArchiveFiles="90"
archiveDateFormat="yyyy-MM-dd"
layout="TimeStamp:${date} —${machinename} - ${message}"
/>
<wrapper-target xsi:type="AsyncWrapper" name="asyncFile">
<target-ref name="toLogFile"/>
</wrapper-target>
</targets> <rules>
<!-- add your logging rules here -->
<logger name="*" minlevel ="Info" writeTo="asyncFile"></logger>
</rules>

二、编写异常错误的处理代码。

$1、读取ErrorCode配置文件中数据。

 namespace NlogTest.Common
{
[XmlRoot("ErrorConfig")]
public class ErrorCodeConfig
{
[XmlArray("ErrorCodes")]
[XmlArrayItem("Error", typeof(ErrorCode))]
public List<ErrorCode> ErrorCodes { get; set; } public static ErrorCodeConfig Config
{
get
{
return XmlHelper.XmlToEntity<ErrorCodeConfig>("ErrorCode");
}
} public static ErrorCode GetError(string errorCode)
{
return Config.ErrorCodes.FirstOrDefault(e => e.Code == errorCode);
}
} public class ErrorCode
{
[XmlAttribute("code")]
public string Code { get; set; } [XmlAttribute("msg")]
public string Message { get; set; } [XmlAttribute("PartialPage")]
public string PartialPage { get; set; } [XmlAttribute("level")]
public string Level { get; set; }
}
}

xmlHelper类:

 namespace NlogTest.Common
{
public class XmlHelper
{
public static string GetXmlPath(string XmlName)
{
string filePath = string.Empty;
filePath = System.Web.HttpContext.Current.Server.MapPath(string.Concat("", "~/Config/"+XmlName + ".Config")); return filePath;
} public static List<T> XmlToEntityList<T>(string XmlName)
{
string xmlPath = GetXmlPath(XmlName);
XmlSerializer serializer = new XmlSerializer(typeof(List<T>));
Object obj = new Object(); if (File.Exists(xmlPath))
{
using (StreamReader reader = new StreamReader(xmlPath))
{
try
{
obj = serializer.Deserialize(reader);
}
catch (Exception ex)
{
//Here put your code witch dealing with exception
}
}
}
return (List<T>)obj;
} public static T XmlToEntity<T>(string XmlName)
{
string xmlPath = GetXmlPath(XmlName);
XmlSerializer serializer = new XmlSerializer(typeof(T));
Object obj = new Object(); if (File.Exists(xmlPath))
{
using (StreamReader reader = new StreamReader(xmlPath))
{
try
{
obj = serializer.Deserialize(reader);
}
catch (Exception ex)
{
//Here put your code witch dealing with exception
}
}
}
return (T)obj;
}
}
}

ErrorConfig文件:

 <?xml version="1.0" encoding="utf-8"?>
<ErrorConfig>
<ErrorCodes> <Error code="1000500" description="GeneralServiceError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/> </ErrorCodes>
</ErrorConfig>

$2、 封装一个Log处理异常错误的类库—LogUtil.

  public class LogUtil
{
private static object mutex = new object(); private static Logger logger = LogManager.GetCurrentClassLogger(); private static LogUtil _instance = null; public static LogUtil Instance
{
get
{
if (_instance == null)
{
lock (mutex)
{
if (_instance == null)
{
_instance = new LogUtil();
}
}
}
return _instance;
}
} public static void Log(int errorCode, string message = null, Exception ex = null)
{
ErrorCode errObj = ErrorCodeConfig.GetError(errorCode.ToString());
if (errObj == null)
{
Instance.LogWarn("Error code " + errorCode + " has no definition.");
return;
} StringBuilder msgBuilder = GenerateMessage(errorCode.ToString(), message, ex); string methodName = "Log" + errObj.Level;
MethodInfo method = typeof(LogUtil).GetMethod(methodName);
if (method == null)
{
Instance.LogWarn("log level wrong,please check ErrorCode.Config.level name is " + errObj.Level);
return;
}
method.Invoke(Instance, new object[] { msgBuilder.ToString() }); } public static void LogDebug(string message)
{
logger.Log(LogLevel.Debug, message);
} public static void LogError(string message)
{
logger.Log(LogLevel.Error, message);
} public void LogErrorException(Exception ex)
{
LogException(LogLevel.Error, ex);
} public void LogFatalException(Exception ex)
{
LogException(LogLevel.Fatal, ex);
} public void LogFatal(string message)
{
logger.Log(LogLevel.Fatal, message);
} public static void LogInfo(string message)
{
logger.Log(LogLevel.Info, message);
} public void LogOff(string message)
{
logger.Log(LogLevel.Off, message);
} public void LogTrace(string message)
{
logger.Log(LogLevel.Trace, message);
} public void LogWarn(string message)
{
logger.Log(LogLevel.Warn, message);
} private static void LogException(LogLevel level, Exception ex)
{
logger.Log(level, GetExceptionMessage(ex));
} private static string GetExceptionMessage(Exception ex)
{
string message = ex.Message;
string stackTrace = ex.StackTrace;
if (string.IsNullOrEmpty(stackTrace) && ex.InnerException != null)
{
stackTrace = ex.InnerException.StackTrace;
}
return message + "::" + stackTrace;
} private static StringBuilder GenerateMessage(string errorCode, string message, Exception ex)
{
StringBuilder msgBuilder = new StringBuilder();
msgBuilder.Append("ErrorCode is " + errorCode);
msgBuilder.Append("\r\n");
if (!string.IsNullOrEmpty(message))
{
msgBuilder.Append(message);
msgBuilder.Append("\r\n");
}
if (ex != null)
{
msgBuilder.Append(GetExceptionMessage(ex));
msgBuilder.Append("\r\n");
}
return msgBuilder;
}
}

三、将LogUtil与MVC衔接上,该MVC中的FilterAttribute、IExceptionFilter出场了。

$1、定义个ErrorFilterAttribute继承FilterAttribute、IExceptionFilter。

 namespace NlogTest.FrameWork
{
public class ErrorFilterAttribute:FilterAttribute,IExceptionFilter
{
private const int commonError = ; public void OnException(ExceptionContext filterContext)
{
int errorCode = commonError;
Exception exception = filterContext.Exception; if (exception is ErrorCodeException)
{
errorCode = ((ErrorCodeException)exception).ErrorCode;
}
string message = "Error";
LogUtil.Log(errorCode,ex:exception,message:message);
}
}
}

$2、将ErrorFilterAttribute注册到App_Start底下的FilterConfig中,这样做的目的是利用MVC中过滤器对全局的controller进行处理。简而言之,比如任意一个controller中action抛出异常错误,这里都会检测到并作为日志记录的接口开始对这些异常错误进行记录。

  public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new HandleErrorAttribute());
filters.Add(new ErrorFilterAttribute());
}
}

2016-12-26

测试效果:

在HomeController中写一段会发生错误的代码:

到在输出目标位置中找对应log文件:

激动的时刻到来了

PS:至此整个Demo算是完成了,快过年了,公司也没啥事,自己捣鼓点东西,基础比较差,就当练手。经过这次,我明白了一件事,平时多积累点小知识点,可以汇集起来再实现一个小功能,新旧知识结合,挺好。

 

NLog在Asp.Net MVC的实战应用的更多相关文章

  1. ASP.NET MVC企业级实战目录

    电子书样稿 (关注最新进度,请加QQ群:161436236) ASP.NET MVC企业实战第1章 MVC开发前奏.pdf ASP.NET MVC企业实战第10章 站内搜索.pdf 已经好长一段时间没 ...

  2. 关于《ASP.NET MVC企业级实战》

    大家好,我的书<ASP.NET MVC企业级实战>已经出版啦,感谢大家过去的关注与支持!前言部分,出版的时候漏了部分内容,我这里将其贴出来. 本书提供源码和教学PPT课件!(源码在书中第3 ...

  3. 《ASP.NET MVC企业实战》(三)MVC开发前奏

    ​ 在上一篇“<ASP.NET MVC企业级实战>(二)MVC开发前奏”中跟随作者大概了解了一些C#3.0和3.5中的新特性.本篇继续以这样的方式来学习C#中的一些特性.   一.C#3. ...

  4. 《ASP.NET MVC企业实战》(二) MVC开发前奏

    ​ 在上一篇“<ASP.NET MVC企业级实战>(一)MVC开发前奏”中记录了作者介绍的一些比较实用的VS使用方法以及C#2.0中添加的新特性.本篇继续大概了解之后版本的一些新特性.   ...

  5. 《ASP.NET MVC企业实战》(一) MVC开发前奏

    一.工具和方法 学到了一些没用过的工具和方法: a)删除多余的using指令并排序:一个类头部的using一般会有很多用不到的,在完成类的编写后,可以右键选择”组织using”来删除没用的using并 ...

  6. ASP.NET MVC 企业级实战

    1.泛型 public class List<T>{ } 当定义泛型类的实例时,必须指定这个实例所存储的实际类型,泛型允许程序员将一个实际的数据类型规约延迟至泛型的实例被创建时才确定,泛型 ...

  7. 基于Bootstrap和Knockout.js的ASP.NET MVC开发实战

    之前在一家公司里用过Knockout,是easyui 和 Knockout结合 的.下面的这本应该不错. 目录 前言 第一部分入门指南 第1章MVC介绍 创建第一个项目 分析HomeControlle ...

  8. WebForms开发方式以及优缺点,来源《ASP.NET MVC企业级实战》

    WebForms有以下3种开发方式 1.服务器端控件 2.一般处理程序+HTML静态页+Ajax 3.一般处理程序+HTML模板 WebForms的请求的是具体的某一个文件.具体的一个类,由客户端发送 ...

  9. 基于Bootstrap和Knockout.js的ASP.NET MVC开发实战 关于 拦截器的 学习 部分

    先贴一段: 下面贴代码: 上面这段代码呢,有几个点迷糊.可以找找看

随机推荐

  1. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  2. 一百元的智能家居——Asp.Net Mvc Api+讯飞语音+Android+Arduino

    大半夜的,先说些废话提提神 如今智能家居已经不再停留在概念阶段,高大上的科技公司都已经推出了自己的部分或全套的智能家居解决方案,不过就目前的现状而言,大多还停留在展厅阶段,还没有广泛的推广起来,有人说 ...

  3. Ubuntu 16.10 安装byzanz截取动态效果图工具

    1.了解byzanz截取动态效果图工具 byzanz能制作文件小,清晰的GIF动态效果图,不足就是,目前只能通过输入命令方式来录制. byzanz主要的参数选项有: -d, --duration=SE ...

  4. JavaScript权威指南 - 数组

    JavaScript数组是一种特殊类型的对象. JavaScript数组元素可以为任意类型,最大容纳232-1个元素. JavaScript数组是动态的,有新元素添加时,自动更新length属性. J ...

  5. UWP开发之Template10实践:本地文件与照相机文件操作的MVVM实例(图文付原代码)

    前面[UWP开发之Mvvmlight实践五:SuspensionManager中断挂起以及复原处理]章节已经提到过Template10,为了认识MvvmLight的区别特做了此实例. 原代码地址:ht ...

  6. IL异常处理

    异常处理在程序中也算是比较重要的一部分了,IL异常处理在C#里面实现会用到一些新的方法 1.BeginExceptionBlock:异常块代码开始,相当于try,但是感觉又不太像 2.EndExcep ...

  7. ExtJS 项目准备工作(一)

    首先,需要从网上下载两个文件,一个是SenchaCmd-6.2.0-windows-64bit(我的电脑是window 10 64位) 另一个是ExtJs6的源码包(ext-6.0.0.415). 源 ...

  8. D3.js学习(六)

    上节我们学习了如何绘制多条曲线, 以及给不同的曲线指定不同的坐标系.在这节当中,我们会对坐标轴标签相关的处理进行学习.首先,我们来想一个问题, 如何我们的x轴上的各个标签的距离比较近,但是标签名又比较 ...

  9. Linux.NET学习手记(7)

    前一篇中,我们简单的讲述了下如何在Linux.NET中部署第一个ASP.NET MVC 5.0的程序.而目前微软已经提出OWIN并致力于发展VNext,接下来系列中,我们将会向OWIN方向转战. 早在 ...

  10. CentOS7 + mono +Jexus 环境的搭建

    CentOS7的安装和配置 1,从http://www.centos.org/下载CentOS7的镜像,并在VMWare中创建该镜像的虚拟机,为方便操作,把虚拟机的网络连接设置为桥接模式:在安装过程中 ...