在上一篇中講解如何做基本的nlog設定檔與建立共用的BaseLog類別,用以處理各種log的寫入。這邊就要來講如何跟.net core MVC互相配合,在甚麼時機點去紀錄log,以快速trace、解決問題。
主要會記錄下列幾項資訊:
使用者的行為
由於現在是使用.net core的Controller類別,跟以前.net framework MVC不太一樣,我們要建立一個BaseCotroller繼承Controller,並且複寫OnActionExecuting與OnActionExecuted方法,執行完再執行底層方法,以下參考官方文件。
public class Test2Controller : Controller
{
public override void OnActionExecuting(ActionExecutingContext context)
{
WriteLog(string.Format("進入點執行了甚麼:{0}",context.HttpContext.Request.Path));
//執行底層方法
base.OnActionExecuting(context);
}
public override void OnActionExecuted(ActionExecutedContext context)
{
WriteLog(string.Format("進入點結束:{0}",context.HttpContext.Request.Path));
//執行底層方法
base.OnActionExecuted(context);
}
}
發生了錯誤
以前.net framework MVC有一個方法叫做OnException,但.net core Controller類別沒有這個方法,必須寫在StartUp中設定,會使用Lambda,以下參考官方文件。
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
context.Response.StatusCode = 500;
context.Response.ContentType = "text/html";
await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n");
await context.Response.WriteAsync("發生錯誤!<br><br>\r\n");
var exceptionHandlerPathFeature =
context.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
WriteLog(string.Format("發生錯誤訊息!:{0}",ex.ToString()));
}
await context.Response.WriteAsync("<a href=\"/\">Home</a><br>\r\n");
await context.Response.WriteAsync("</body></html>\r\n");
await context.Response.WriteAsync(new string(' ', 512)); // IE padding
});
});
app.UseHsts();
}
SQL語法
還記得在Model的第三個部分有建立底層的資料處理方法,執行Dapper前先執行Execute與Query方法,這邊就直接把WriteLog程式寫在這兩個方法就可以記錄執行過的SQL指令!
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Threading.Tasks;
using Dapper;
namespace IronMan
{
public class DataControl : IDisposable
{
private IDbConnection db = null;
private string _connectStr;
//建構子初始化連線字串/DB連接
public DataControl()
{
string connectionStr = @"放上你的資料庫連線字串";
_connectStr = connectionStr;
db = new SqlConnection(_connectStr);
}
//共用查詢方法
public IEnumerable<T> Query<T>(string sql,object param)
{
//這邊寫下Log紀錄,param參數可使用reflection.PropertyInfo來解析出來
WriteLog(string.Format("執行了:{0}",sql));
return db.Query<T>(sql, param).ToList();
}
//共用新增刪除修改方法
public int Execute(string sql, object param)
{
//這邊寫下Log紀錄,param參數可使用reflection.PropertyInfo來解析出來
WriteLog(string.Format("執行了:{0}",sql));
return db.Execute(sql, param);
}
//釋放連接
public void Dispose()
{
db.Dispose();
}
}
}
參考資料
https://docs.microsoft.com/zh-tw/aspnet/core/fundamentals/error-handling?view=aspnetcore-3.1
https://docs.microsoft.com/zh-tw/aspnet/core/mvc/controllers/filters?view=aspnetcore-3.1