NLog在Asp.Net MVC的實戰應用

来源:http://www.cnblogs.com/kejie/archive/2016/12/22/6211597.html
-Advertisement-
Play Games

Asp.Net MVC FilterAttribute特性、讀取xml反序列化、NLog實戰系列文章 首先新建一個MVC project。 一、NLog的配置。 作者:Jarosław Kowalski <[email protected]> 翻譯:CrazyCoder 原文:http://www ...


Asp.Net MVC FilterAttribute特性讀取xml反序列化、NLog實戰系列文章

首先新建一個MVC project。

一、NLog的配置。

作者:Jarosław Kowalski <[email protected]>

翻譯:CrazyCoder

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

更多關於NLog的中文文章,請參考《NLog文章系列》。

(1)在當前project中引用NLog相關dll文件。

 

 

 

 

此時會發現project底下多了兩個文件。可以自己新建一個Config文件夾,把這兩個文件移進去。

 

(2)接下來就是根據自己個人需求配置NLog。

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

    

1 <configuration>
2   <configSections>
3     <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
4   </configSections>
5   <nlog>
6     <include file="${basedir}/Config/NLog.config" /><!--包含文件 此處配置為前面引用NLog時添加的NLog.config文件-->
7   </nlog>
8 </configuration>

   $2、一個新添加的NLog.config是沒有指定"輸出目標“和"規則"的,所以我們自己添加targets和rules。

 

 1 <targets>
 2    <target name="toLogFile" xsi:type="File"
 3        archiveAboveSize="2097152"
 4        fileName="d:/LogFiles/NLogTest/${shortdate}.log"
 5        archiveFileName="d:/LogFiles/NLogTest/{#}.txt"
 6        archiveNumbering="DateAndSequence"
 7        archiveEvery="Day"
 8        maxArchiveFiles="90"
 9        archiveDateFormat="yyyy-MM-dd"
10        layout="TimeStamp:${date} —${machinename} - ${message}"
11                 />
12     <wrapper-target xsi:type="AsyncWrapper" name="asyncFile">
13       <target-ref name="toLogFile"/>
14     </wrapper-target>
15   </targets>
16 
17 <rules>
18     <!-- add your logging rules here -->
19     <logger name="*" minlevel ="Info" writeTo="asyncFile"></logger>
20 </rules>

二、編寫異常錯誤的處理代碼。

 $1、讀取ErrorCode配置文件中數據。

 

 1 namespace NlogTest.Common
 2 {   
 3     [XmlRoot("ErrorConfig")]
 4     public class ErrorCodeConfig
 5     {
 6         [XmlArray("ErrorCodes")]
 7         [XmlArrayItem("Error", typeof(ErrorCode))]
 8         public List<ErrorCode> ErrorCodes { get; set; }
 9 
10         public static ErrorCodeConfig Config
11         {
12             get
13             {
14                 return XmlHelper.XmlToEntity<ErrorCodeConfig>("ErrorCode");
15             }
16         }
17 
18         public static ErrorCode GetError(string errorCode)
19         {
20             return Config.ErrorCodes.FirstOrDefault(e => e.Code == errorCode);
21         }
22     }
23 
24     public class ErrorCode
25     {
26         [XmlAttribute("code")]
27         public string Code { get; set; }
28 
29         [XmlAttribute("msg")]
30         public string Message { get; set; }
31 
32         [XmlAttribute("PartialPage")]
33         public string PartialPage { get; set; }
34 
35         [XmlAttribute("level")]
36         public string Level { get; set; }
37     }
38 }

xmlHelper類:

 

 1 namespace NlogTest.Common
 2 {
 3     public class XmlHelper
 4     {
 5         public static string GetXmlPath(string XmlName)
 6         {
 7             string filePath = string.Empty;
 8             filePath = System.Web.HttpContext.Current.Server.MapPath(string.Concat("", "~/Config/"+XmlName + ".Config"));
 9 
10             return filePath;
11         }
12 
13         public static List<T> XmlToEntityList<T>(string XmlName)
14         {
15             string xmlPath = GetXmlPath(XmlName);
16             XmlSerializer serializer = new XmlSerializer(typeof(List<T>));
17             Object obj = new Object();
18 
19             if (File.Exists(xmlPath))
20             {
21                 using (StreamReader reader = new StreamReader(xmlPath))
22                 {
23                     try
24                     {
25                         obj = serializer.Deserialize(reader);
26                     }
27                     catch (Exception ex)
28                     {
29                         //Here put your code witch dealing with exception
30                     }
31                 }
32             }
33             return (List<T>)obj;
34         }
35 
36         public static T XmlToEntity<T>(string XmlName)
37         {
38             string xmlPath = GetXmlPath(XmlName);
39             XmlSerializer serializer = new XmlSerializer(typeof(T));
40             Object obj = new Object();
41 
42             if (File.Exists(xmlPath))
43             {
44                 using (StreamReader reader = new StreamReader(xmlPath))
45                 {
46                     try
47                     {
48                         obj = serializer.Deserialize(reader);
49                     }
50                     catch (Exception ex)
51                     {
52                         //Here put your code witch dealing with exception
53                     }
54                 }
55             }
56             return (T)obj;
57         }
58     }
59 }

 

 ErrorConfig文件:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <ErrorConfig>
 3   <ErrorCodes>
 4     <!--Service Errors-->
 5     <Error code="1000500" description="GeneralServiceError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
 6     <!--Address-->
 7     <Error code="1101500" description="GetCitiesError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
 8     <Error code="1102500" description="GetStatesError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
 9     <Error code="1103500" description="GetPostalCodesError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
10     <!--AgreementDoc-->
11     <Error code="1201500" description="GetAgreementDocError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
12     <!--Image Upload-->
13     <Error code="1301500" description="PostImagesError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
14     <Error code="1302500" description="ImageStreamEmpty" msg="" PartialPage="ErrorPartial/GlobalError" level="Info"/>
15     <!--Agreement-->
16     <Error code="1401500" description="PostAgreementError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
17     <Error code="1402500" description="ValidateAgreementError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
18     <Error code="1403400" description="InvalidGovernmentId" msg="" PartialPage="ErrorPartial/GlobalError" level="Info"/>
19     <Error code="1404500" description="AgreementProcessorError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
20     <Error code="1405500" description="InvalidEmailId" msg="" PartialPage="ErrorPartial/GlobalError" level="Info"/>
21     <Error code="1406500" description="DuplicateConsultant" msg="" PartialPage="ErrorPartial/GlobalError" level="Info"/>
22     <!--Consultant-->
23     <Error code="1501500" description="GetConsultantError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
24     <Error code="1502500" description="GetConsultantListError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
25     <Error code="1503500" description="GetUnitMemberListError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
26     <Error code="1504400" description="ConsultantIdNotEmpty" msg="" PartialPage="ErrorPartial/GlobalError" level="Info"/>
27     <Error code="1505400" description="ConsultantListLessParams" msg="" PartialPage="ErrorPartial/GlobalError" level="Info"/>
28     <Error code="1506500" description="ConsultantIsInRoleError" msg="" PartialPage="ErrorPartial/GlobalError" level="Info"/>
29     <!--Domain-->
30     <Error code="1601500" description="GetBanksError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
31     <Error code="1602500" description="GetRacesError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
32     <Error code="1603500" description="ValidateGovernmentIdError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
33     <Error code="1604500" description="GetGateError" msg="" PartialPage="ErrorPartial/GlobalError" level="Error"/>
34 
35     <!--end service-->
36 
37     <!--Web Errors-->
38 
39     <!--Unexpected Web Error-->
40     <Error code="2000500" description="" msg="" PartialPage="ErrorPartial/GlobalError" level="Info"></Error>
41 
42     <!--Home Controller Error start with 1-->
43     <Error code="2101400" description="" msg="RecruitInfo_Not_Eligible" PartialPage="ErrorPartial/NotEligibleRecruit" level="Info"></Error>
44 
45     <!--Reminder Controller Error start with 2-->
46     <!--PersonalInformation Controller Error start with 3-->
47     <!--Review Controller Error start with 4-->
48     <!--Imageupload Controller Error start with 5-->
49 
50     <!--confirmation Controller Error start with 6-->
51     <Error code="2601400" description="Session ConfirmationViewModel is null" msg="" PartialPage="ErrorPartial/GlobalError" level="Info"/>
52 
53     <Error code="2701500" description="can not access service" msg="" PartialPage="ErrorPartial/GlobalError" level="Info"/>
54 
55     <!--end Web Errors-->
56 
57   </ErrorCodes>
58 </ErrorConfig>

 

 $2、 封裝一個Log處理異常錯誤的類庫—LogUtil.

    

  1  public class LogUtil
  2     {
  3         private static object mutex = new object();
  4 
  5         private static Logger logger = LogManager.GetCurrentClassLogger();
  6 
  7         private static LogUtil _instance = null;
  8 
  9         public static LogUtil Instance
 10         {
 11             get
 12             {
 13                 if (_instance == null)
 14                 {
 15                     lock (mutex)
 16                     {
 17                         if (_instance == null)
 18                         {
 19                             _instance = new LogUtil();
 20                         }
 21                     }
 22                 }
 23                 return _instance;
 24             }
 25         }
 26 
 27         public static void Log(int errorCode, string message = null, Exception ex = null)
 28         {
 29             ErrorCode errObj = ErrorCodeConfig.GetError(errorCode.ToString());
 30             if (errObj == null)
 31             {
 32                 Instance.LogWarn("Error code " + errorCode + " has no definition.");
 33                 return;
 34             }
 35 
 36             StringBuilder msgBuilder = GenerateMessage(errorCode.ToString(), message, ex);
 37 
 38             string methodName = "Log" + errObj.Level;
 39             MethodInfo method = typeof(LogUtil).GetMethod(methodName);
 40             if (method == null)
 41             {
 42                 Instance.LogWarn("log level wrong,please check ErrorCode.Config.level name is " + errObj.Level);
 43                 return;
 44             }
 45             method.Invoke(Instance, new object[] { msgBuilder.ToString() });
 46 
 47         }
 48 
 49         public static void LogDebug(string message)
 50         {
 51             logger.Log(LogLevel.Debug, message);
 52         }
 53 
 54         public static void LogError(string message)
 55         {
 56             logger.Log(LogLevel.Error, message);
 57         }
 58 
 59         public void LogErrorException(Exception ex)
 60         {
 61             LogException(LogLevel.Error, ex);
 62         }
 63 
 64         public void LogFatalException(Exception ex)
 65         {
 66             LogException(LogLevel.Fatal, ex);
 67         }
 68 
 69         public void LogFatal(string message)
 70         {
 71             logger.Log(LogLevel.Fatal, message);
 72         }
 73 
 74         public static void LogInfo(string message)
 75         {
 76             logger.Log(LogLevel.Info, message);
 77         }
 78 
 79         public void LogOff(string message)
 80         {
 81             logger.Log(LogLevel.Off, message);
 82         }
 83 
 84         public void LogTrace(string message)
 85         {
 86             logger.Log(LogLevel.Trace, message);
 87         }
 88 
 89         public void LogWarn(string message)
 90         {
 91             logger.Log(LogLevel.Warn, message);
 92         }
 93 
 94 
 95         private static void LogException(LogLevel level, Exception ex)
 96         {
 97             logger.Log(level, GetExceptionMessage(ex));
 98         }
 99 
100         private static string GetExceptionMessage(Exception ex)
101         {
102             string message = ex.Message;
103             string stackTrace = ex.StackTrace;
104             if (string.IsNullOrEmpty(stackTrace) && ex.InnerException != null)
105             {
106                 stackTrace = ex.InnerException.StackTrace;
107             }
108             return message + "::" + stackTrace;
109         }
110 
111         private static StringBuilder GenerateMessage(string errorCode, string message, Exception ex)
112         {
113             StringBuilder msgBuilder = new StringBuilder();
114             msgBuilder.Append("ErrorCode is " + errorCode);
115             msgBuilder.Append("\r\n");
116             if (!string.IsNullOrEmpty(message))
117             {
118                 msgBuilder.Append(message);
119                 msgBuilder.Append("\r\n");
120             }
121             if (ex != null)
122             {
123                 msgBuilder.Append(GetExceptionMessage(ex));
124                 msgBuilder.Append("\r\n");
125             }
126             return msgBuilder;
127         }
128     }

 

三、將LogUtil與MVC銜接上,該MVC中的FilterAttribute、IExceptionFilter出場了。

   $1、定義個ErrorFilterAttribute繼承FilterAttribute、IExceptionFilter。

 1 namespace NlogTest.FrameWork
 2 {
 3     public class ErrorFilterAttribute:FilterAttribute,IExceptionFilter
 4     {
 5         private const int commonError = 2000500;
 6 
 7         public void OnException(ExceptionContext filterContext)
 8         {
 9             int errorCode = commonError;
10             Exception exception = filterContext.Exception;
11 
12             if (exception is ErrorCodeException)
13             {
14                 errorCode = ((ErrorCodeException)exception).ErrorCode;
15             }
16             string message = "Error";
17             LogUtil.Log(errorCode,ex:exception,message:message);
18         }
19     }
20 }

$2、將ErrorFilterAttribute註冊到App_Start底下的FilterConfig中,這樣做的目的是利用MVC中過濾器對全局的controller進行處理。簡而言之,比如任意一個controller中action拋出異常錯誤,這裡都會檢測到並作為日誌記錄的介面開始對這些異常錯誤進行記錄。

測試效果:

在HomeController中寫一段會發生錯誤的代碼:

 到在輸出目標位置中找對應log文件:

激動的時刻到來了

PS:至此整個Demo算是完成了,快過年了,公司也沒啥事,自己搗鼓點東西,基礎比較差,就當練手。經過這次,我明白了一件事,平時多積累點小知識點,可以彙集起來再實現一個小功能,新舊知識結合,挺好。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 不久前,我發佈了一個調試工具:發佈:.NET開發人員必備的可視化調試工具(你值的擁有)不久前,我發佈了一個調試工具:發佈:.NET開發人員必備的可視化調試工具(你值的擁有) 效果是這樣的:之後,有小部分用戶反映,工具不生效~~~然後,建議小部分用戶換個電腦環境試試,就好了~~~於是... ...
  • 在ASP.NET MVC程式中,需要給一個radio list表綁定一個值。下麵是Insus.NET實現的方法: 使用foreach來迴圈radio每一個選項,如果值與選項的值相同,那這個選項為選中,反之為未選。 如果覺得html有點多,可以稍修改如下: 使用 bool ? object : obj ...
  • 一、演示: 介面查看:http://apidoc.docode.top/ 介面後臺:http://apiadmin.docode.top/ 登錄:administrator,123456 二、使用到的技術: ①、AdminLite(基於Bootstrap的響應式UI模板) ②、ASP.NET MVC ...
  • 支持Oracle、MSSQL、MySQL、SQLite四種資料庫,支持事務,支持對象關係映射;已在多個項目中實際使用。 沒有語法糖,學習成本幾乎為0,拿來即用。 DBHelper類完整代碼: using System; using System.Collections.Generic; using ...
  • 效果圖 思路 拿到父級窗體的內容,放入一個容器里,再在容器里放入一個半透明層.將整個容器賦給父級窗體的內容. 關閉時反向操作. 代碼 消息窗彈出時 消息框關閉時 源碼下載:MessageBoxWithLayer.zip ...
  • 上一篇文章學習了IL的入門,接下來我們再通過兩個例子來瞭解下類的屬性、構造函數以及介面的使用 一、類的屬性、構造函數 1、先看下我們要構建的類的C#代碼,然後再進行IL的實現,示例代碼如下: [Serializable] public class Dynamic { public int _a = ...
  • 在上一篇多線程(線程同步1)中,我們主要學習了執行基本的原子操作、使用Mutex構造以及SemaphoreSlim構造,在這一篇中我們主要學習如何使用AutoResetEvent構造、ManualResetEventSlim構造和CountDownEvent構造。 四、使用AutoResetEven ...
  • 這篇分享一下 ASP.NET MVC許可權控制。也就是說某一用戶登錄之後,某一個用戶是否有許可權訪問Controller,Action(操作),視圖等想實現這些功能,需要在資料庫創建好幾個表:[User],[Module],[Form],[Action],[Role],[RoleModule],[Use ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...