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开发实战 关于 拦截器的 学习 部分
先贴一段: 下面贴代码: 上面这段代码呢,有几个点迷糊.可以找找看
随机推荐
- java基础集合经典训练题
第一题:要求产生10个随机的字符串,每一个字符串互相不重复,每一个字符串中组成的字符(a-zA-Z0-9)也不相同,每个字符串长度为10; 分析:*1.看到这个题目,或许你脑海中会想到很多方法,比如判 ...
- hibernate多对多关联映射
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
- Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程+事物案例演示
Dapper的牛逼就不扯蛋了,答应群友做个入门Demo的,现有园友需要,那么公开分享一下: 完整Demo:http://pan.baidu.com/s/1i3TcEzj 注 意 事 项:http:// ...
- .NET Core的日志[2]:将日志输出到控制台
对于一个控制台应用,比如采用控制台应用作为宿主的ASP.NET Core应用,我们可以将记录的日志直接输出到控制台上.针对控制台的Logger是一个类型为ConsoleLogger的对象,Consol ...
- mybatis_常用标签
1.<where></where>标签的作用 可以动态的添加where关键字 可以自动去掉第一个拼接条件的and关键字 <where> <if test=&q ...
- Linux学习之探索文件系统
Linux,一起学习进步- ls With it, we can see directory contents and determine a variety of important file ...
- Smarty的基本使用与总结
含义: Smarty是PHP的一个引擎模板,可以更好的进行逻辑与显示的分离,即我们常说的MVC,这个引擎的作用就是将C分离出来. 环境需求:PHP5.2或者更高版本 我使用的环境是:PHP5.3,wi ...
- 【干货分享】流程DEMO-固定资产转移流程
流程名: 固定资产转移 业务描述: 固定资产从某员工转移至另一员工,转出人与转入人必须不同 流程相关文件: 流程包.xml 流程说明: 直接导入流程包文件,即可使用本流程 表单: 流程: ...
- 在Ubuntu下搭建Spark群集
在前一篇文章中,我们已经搭建好了Hadoop的群集,接下来,我们就是需要基于这个Hadoop群集,搭建Spark的群集.由于前面已经做了大量的工作,所以接下来搭建Spark会简单很多. 首先打开三个虚 ...
- SQLite学习笔记(十)&&加密
随着移动互联网的发展,手机使用越来越广泛,sqlite作为手机端存储的一种解决方案,使用也非常普遍.但是sqlite本身安全特性却比较弱,比如不支持用户权限,只要能获取到数据库文件就能进行访问:另外也 ...