NLog在Asp.Net MVC的实战应用
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的实战应用的更多相关文章
- ASP.NET MVC企业级实战目录
电子书样稿 (关注最新进度,请加QQ群:161436236) ASP.NET MVC企业实战第1章 MVC开发前奏.pdf ASP.NET MVC企业实战第10章 站内搜索.pdf 已经好长一段时间没 ...
- 关于《ASP.NET MVC企业级实战》
大家好,我的书<ASP.NET MVC企业级实战>已经出版啦,感谢大家过去的关注与支持!前言部分,出版的时候漏了部分内容,我这里将其贴出来. 本书提供源码和教学PPT课件!(源码在书中第3 ...
- 《ASP.NET MVC企业实战》(三)MVC开发前奏
在上一篇“<ASP.NET MVC企业级实战>(二)MVC开发前奏”中跟随作者大概了解了一些C#3.0和3.5中的新特性.本篇继续以这样的方式来学习C#中的一些特性. 一.C#3. ...
- 《ASP.NET MVC企业实战》(二) MVC开发前奏
在上一篇“<ASP.NET MVC企业级实战>(一)MVC开发前奏”中记录了作者介绍的一些比较实用的VS使用方法以及C#2.0中添加的新特性.本篇继续大概了解之后版本的一些新特性. ...
- 《ASP.NET MVC企业实战》(一) MVC开发前奏
一.工具和方法 学到了一些没用过的工具和方法: a)删除多余的using指令并排序:一个类头部的using一般会有很多用不到的,在完成类的编写后,可以右键选择”组织using”来删除没用的using并 ...
- ASP.NET MVC 企业级实战
1.泛型 public class List<T>{ } 当定义泛型类的实例时,必须指定这个实例所存储的实际类型,泛型允许程序员将一个实际的数据类型规约延迟至泛型的实例被创建时才确定,泛型 ...
- 基于Bootstrap和Knockout.js的ASP.NET MVC开发实战
之前在一家公司里用过Knockout,是easyui 和 Knockout结合 的.下面的这本应该不错. 目录 前言 第一部分入门指南 第1章MVC介绍 创建第一个项目 分析HomeControlle ...
- WebForms开发方式以及优缺点,来源《ASP.NET MVC企业级实战》
WebForms有以下3种开发方式 1.服务器端控件 2.一般处理程序+HTML静态页+Ajax 3.一般处理程序+HTML模板 WebForms的请求的是具体的某一个文件.具体的一个类,由客户端发送 ...
- 基于Bootstrap和Knockout.js的ASP.NET MVC开发实战 关于 拦截器的 学习 部分
先贴一段: 下面贴代码: 上面这段代码呢,有几个点迷糊.可以找找看
随机推荐
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- Angular2入门系列教程2-项目初体验-编写自己的第一个组件
上一篇 使用Angular-cli搭建Angular2开发环境 Angular2采用组件的编写模式,或者说,Angular2必须使用组件编写,没有组件,你甚至不能将Angular2项目启动起来 紧接着 ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- 关于 CSS 反射倒影的研究思考
原文地址:https://css-tricks.com/state-css-reflections 译者:nzbin 友情提示:由于演示 demo 的兼容性,推荐火狐浏览.该文章篇幅较长,内容庞杂,有 ...
- CRL快速开发框架系列教程五(使用缓存)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- angular 源码分析 1 - angularInit()
angularjs 是个神奇的框架,由于我的好奇,想了解她的内部工作原理,只能一步一步的走进她,靠近她,和她深入的交流. angularjs 的入口是什么样子的呢?一起掀起她的盖头吧. 在这里我只讲方 ...
- 深入浅出Redis-redis哨兵集群
1.Sentinel 哨兵 Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所 ...
- 星浩资本快速发展引擎:IT就是生产力
星浩资本成立于2010年,是一家涵盖私募基金.开发管理.商业与现代服务业三大业务范围的综合性管理公司,专注于投资中国首创.高成长性.高回报率的创新型城市综合体. 年轻的星浩资本在商业投资上有其独到的商 ...
- 转:ORA-15186: ASMLIB error function = [asm_open], error = [1], 2009-05-24 13:57:38
转:ORA-15186: ASMLIB error function = [asm_open], error = [1], 2009-05-24 13:57:38http://space.itpub. ...
- 关系型数据库与NoSQL数据库
关系型数据库的优缺点 优点: 可以做事务处理,从而保证了数据的一致性: 可以进行JOIN等多表查询: 由于以SQL标准化为前提,数据更新的开销很小(相同的字段基本上都只有一处). 缺点: 大量数据的写 ...