上一篇 [ASP.NET MVC] 自訂Global ErrorHandler 紀錄請求參數 沒有處理到 Ajax,這篇繼續補完...
開發環境
- VS 2017
- .NET Framework 4.7.2
- .NLog 4.6.3
若對 ErrorHandler 使用方式不熟悉的,請參考
https://shiyousan.com/post/635838881238204198
沿用上一篇的範例
https://dotblogs.com.tw/yc421206/2019/05/16/asp_mvc_global_exception_handler_log_request_variable
實作
GlobalHandleErrorAttribute 做了兩件事
- 加上 filterContext.HttpContext.Request.IsAjaxRequest() 的判斷
- 由於調用端可能是來自別人寫的前端,為了例外保護訊息,IsDebuggingEnabled 判斷是否呈現例外的設定,就不像上一篇那樣放在 cshtml,而是直接在後端處理完
if (filterContext.HttpContext.Request.IsAjaxRequest()) { dynamic data; if (filterContext.HttpContext.IsDebuggingEnabled) { data = new { filterContext.Exception.Message, filterContext.Exception.StackTrace, RequestVariable = request }; } else { data = new { Message = "An unexpected error has occurred. Please contact the system administrator." }; } filterContext.Result = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet, Data = data }; }
HomeController 新增加一個 Action,模擬例外,我註解的扣可以解開觀察一下他的效果
[HttpGet] public ActionResult Query(string id) { var employee = new Employee { Id = Guid.NewGuid(), Name = "yao", Age = 19 }; InstanceUtility.HttpRequestState.SetCurrentVariable(employee); if (string.IsNullOrEmpty(id)) { throw new Exception("壞掉了"); //return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Id not be empty"); //return this.HttpNotFound(); //return this.Json(new // { // Id = id, // Success = false, // ErrorMessage = "Id not be empty" // }, // JsonRequestBehavior.AllowGet); } return this.Json(new {Success = true, Id = id}, JsonRequestBehavior.AllowGet); }
在 Index.cshtml 打 Query Action
@section Scripts { <script type="text/javascript"> var url = '@Html.Raw(Url.Action("Query", "Home"))'; $.ajax({ url: url, type: 'Get', contentType: "application/json;charset=utf-8", success: function(request, status, data) { if (data.Success) { alert('OK!!!'); } else { alert('Oops..' + data.statusText); } }, error: function(xhr, status, error) { console.log("statusText:" + xhr.statusText); //ErrorMessage console.log("responseText:" + xhr.responseText); //StackTrace (if debug or overridden) console.log("status:" + xhr.status); //Numeric status code var errorMessage = ""; if (xhr.status === 500) { var exception = JSON.parse(xhr.responseText); errorMessage = "error:" + exception.Message + ",request:" +JSON.stringify( exception.RequestVariable) ; } else { errorMessage = error; } alert(errorMessage); } }); </script> }
執行結果
訊息好像太多了,需要再依需求修改
到目前為止這個 Handler 就能同時處理Ajax、cshtml,有需要的話再來調整
如果,你想要使用文本,可以使用 ContentResult
var content = filterContext.HttpContext.IsDebuggingEnabled ? filterContext.Exception.StackTrace : "An unexpected error has occurred. Please contact the system administrator."; filterContext.Result = new ContentResult { ContentType = "text/plain", Content = content }; filterContext.HttpContext.Response.Status = "500 " + filterContext.Exception.Message .Replace("\r", " ") .Replace("\n", " ");
還有更多的 ActionResult....
專案路徑
https://github.com/yaochangyu/sample.dotblog/tree/master/MVC5/ErrorHandlers
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET