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开发实战 关于 拦截器的 学习 部分
先贴一段: 下面贴代码: 上面这段代码呢,有几个点迷糊.可以找找看
随机推荐
- Sql Server系列:分区表操作
1. 分区表简介 分区表在逻辑上是一个表,而物理上是多个表.从用户角度来看,分区表和普通表是一样的.使用分区表的主要目的是为改善大型表以及具有多个访问模式的表的可伸缩性和可管理性. 分区表是把数据按设 ...
- 说说Makefile那些事儿
说说Makefile那些事儿 |扬说|透过现象看本质 工作至今,一直对Makefile半知半解.突然某天幡然醒悟,觉得此举极为不妥,只得洗心革面从头学来,以前许多不明觉厉之处顿时茅塞顿开,想想好记性不 ...
- js实现前端分页页码管理
用JS实现前端分页页码管理,可以很美观的区分页码显示(这也是参考大多数网站的分页页码展示),能够有很好的用户体验,这也是有业务需要就写了一下,还是新手,经验不足,欢迎指出批评! 首先先看效果图: 这是 ...
- 【.net 深呼吸】跨应用程序域执行程序集
应用程序域,你在网上可以查到它的定义,凡是概念性的东西,大伙儿只需要会搜索就行,内容看了就罢,不用去记忆,更不用去背,“名词解释”是大学考试里面最无聊最没水平的题型. 简单地说,应用程序域让你可以在一 ...
- PowerDesigner-VBSrcipt-自动设置主键,外键名等(SQL Server)
在PowerDesigner中的设计SQL Server 数据表时,要求通过vbScript脚本实现下面的功能: 主键:pk_TableName 外键:fk_TableName_ForeignKeyC ...
- nodejs模块发布及命令行程序开发
前置技能 npm工具为nodejs提供了一个模块和管理程序模块依赖的机制,当我们希望把模块贡献出去给他人使用时,可以把我们的程序发布到npm提供的公共仓库中,为了方便模块的管理,npm规定要使用一个叫 ...
- 深入浅出JavaScript之闭包(Closure)
闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.下面写下我的学习笔记~ 闭包-无处不 ...
- JAVA FreeMarker工具类
FreeMarkerUtil.java package pers.kangxu.datautils.utils; import java.io.File; import java.io.StringW ...
- canvas快速绘制圆形、三角形、矩形、多边形
想看前面整理的canvas常用API的同学可以点下面: canvas学习之API整理笔记(一) canvas学习之API整理笔记(二) 本系列文章涉及的所有代码都将上传至:项目代码github地址,喜 ...
- [OC] NSURLSession
有的程序员老了,还没听过NSURLSession 有的程序员还嫩,没用过NSURLConnection 有的程序员很单纯,他只知道AFN. NSURLConnection在iOS9被宣布弃用,NSUR ...