文章出處
文章列表
女朋友不是想拋就拋,但異常卻可以,不信請往下看。
今天在MVC Controller中寫代碼時,糾結了一下:
public async Task<ActionResult> Save(int? postId) { if(!IsOwner(postId.Value, userId)) { //拋不拋異常呢? } }
在這個地方要不要拋異常呢?
如果不拋異常,就得這么寫:
public async Task<ActionResult> Save(int? postId) { if(!IsOwner(postId.Value, userId)) { return Json(new { isSuccess = false, message = "嘗試執行未經授權的操作" }); } }
而且通常在這樣的情況下,還需要記錄日志,于是代碼變成:
if(!IsOwner(postId.Value, userId)) { Logger.Default.Info("UnauthorizedSave", "..."); return Json(new { isSuccess = false, message = "嘗試執行未經授權的操作" }); }
如果拋異常呢,代碼就可以這么寫:
if(IsOwner(postId.Value, userId)) { throw new UnauthorizedAccessException(); }
代碼顯得更簡潔,更具表達力,而且記錄錯誤日志可以在Application_Error中統一處理:
protected void Application_Error(Object sender, EventArgs e) { var lastError = Server.GetLastError(); if (lastError != null) { Logger.Default.Error("Application_Error", lastError); Response.StatusCode = 500; Server.ClearError(); } }
但這會帶來一個問題,客戶端收到的將是自定義500錯誤頁面的html代碼,不僅沒有具體的錯誤信息,而且在ajax回調時還要額外處理,而通常我們最期待的是一個json格式的返回結果。
于是要想實現“想拋就拋”,就必須解決:如何在Application_Error中統一處理ajax請求處理過程中產生的異常,并將之轉換成json格式的響應內容返回給客戶端。
分解一下,就變成了2個問題:
1)如何在Application_Error中判斷一個請求是否是ajax請求?
今天上午通過MVC的擴展方法IsAjaxRequest解決了,詳見如何在Global.asax中判斷是否是ajax請求:
if ((new HttpRequestWrapper(Request)).IsAjaxRequest()) { }
2)如何生成json格式的響應內容并返回給客戶端?
這個可以通過Json.NET+Response.Write來解決,代碼如下:
Response.Clear(); Response.ContentType = "application/json; charset=utf-8"; Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject( new { isSuccess = false, message = lastError.Message })); Response.Flush();
最終實現“想拋就拋”的代碼如下:
protected void Application_Error(Object sender, EventArgs e) { var lastError = Server.GetLastError(); if (lastError != null) { CNBlogs.Infrastructure.Logging.Logger.Default.Error("Application_Error", lastError); if(Request != null && (new HttpRequestWrapper(Request)).IsAjaxRequest()) { Response.Clear(); Response.ContentType = "application/json; charset=utf-8"; Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject( new { isSuccess = false, message = lastError.Message })); Response.Flush(); Server.ClearError(); return; } Response.StatusCode = 500; Server.ClearError(); } }
ajax客戶端收到的結果如下:
從此,可以盡情地拋異常了。
文章列表
全站熱搜