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开发实战 关于 拦截器的 学习 部分
先贴一段: 下面贴代码: 上面这段代码呢,有几个点迷糊.可以找找看
随机推荐
- mobx @computed的解读
写在前面:我一开始看不懂官网的@computed的作用,因为即使我把@computed去掉,依然能正确的report,然后我百度谷歌都找不到答案,下面都是我自己的理解,如果是有问题的,不对的,请务必留 ...
- C语言 · 4_2找公倍数
问题描述 这里写问题描述. 打印出1-1000所有11和17的公倍数. 样例输入 一个满足题目要求的输入范例.例:无 样例输出 与上面的样例输入对应的输出.例: 代码如下: #include< ...
- Ubuntu 16.10 安装KolourPaint 4画图工具
KolourPaint 4画图工具简单实用,可以绘画.视频处理和图标编辑: • 绘画:绘制图表和“手绘” • 视频处理:编辑截图和照片;应用特效 • 图标编辑:绘画剪贴和标识透明化 1.在Ubuntu ...
- Win.ini和注册表的读取写入
最近在做打包的工作,应用程序的配置信息可以放在注册表文件中,但是在以前的16位操作系统下,配置信息放在Win.ini文件中.下面介绍一下Win.ini文件的读写方法和注册表的编程. 先介绍下Win.i ...
- C++整数转字符串的一种方法
#include <sstream> //ostringstream, ostringstream::str() ostringstream stream; stream << ...
- Maven仓库搭建和配置
maven在本地搭建仓库的实际需求maven在项目构建过程需要下载一些必要的软件包,这些默认的下载链接都是访问maven的远程中央仓库Central Repo.如果项目中的成员,每次第一次构建的时候都 ...
- mysql 写入优化
1 主从分离 从表读取,主表可以去掉索引 2 先写入到文件或redis,定时刷新到库 3 用nginx 4 分库 分表 每个库表的数据总量少了 插入会快一点 5 最大限度减少查库的次数 6 一条sql ...
- QDEZ集训笔记【更新中】
这是一个绝妙的比喻,如果青岛二中的台阶上每级站一只平度一中的猫,差不多站满了吧 自己的理解 [2016-12-31] [主席树] http://www.cnblogs.com/candy99/p/61 ...
- Vue.js——60分钟组件快速入门(上篇)
组件简介 组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树: 那么什么是组件呢?组件可以扩展HTML ...
- mono3.2和monodevelop4.0在ubuntu12.04上两天的苦战
首先第一步是设置ubuntu server 12.04版更新源,推荐中科大的比较快:deb http://debian.ustc.edu.cn/ubuntu/ precise main multive ...