欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ASP.NET MVC中異常Exception攔截的深入理解

 更新時間:2018年07月02日 10:04:37   作者:沉淀的風(fēng)  
異常信息的處理在程序中非常重要, 在asp.net mvc中提供異常屬性攔截器進(jìn)行對異常信息的處理,下面這篇文章主要給大家介紹了關(guān)于ASP.NET MVC中異常Exception攔截的相關(guān)資料,需要的朋友可以參考下

一、前言

由于客戶端的環(huán)境不一致,有可能會造成我們預(yù)計不到的異常錯誤,所以在項目中,友好的異常信息提示,是非常重要的。在asp.net mvc中實現(xiàn)異常屬性攔截也非常簡單,只需要繼承另一個類(System.Web.Mvc.FilterAttribute)和一個接口(System.Web.Mvc.IExceptionFilter),實現(xiàn)接口里面OnException方法,或者直接繼承Mvc 提供的類System.Web.Mvc.HandleErrorAttribute。

下面話不多說了,來一起看看詳細(xì)的介紹吧

二、實現(xiàn)關(guān)鍵邏輯

繼承System.Web.Mvc.HandleErrorAttribute,重寫了OnException方法,主要實現(xiàn)邏輯代碼如下:

public class HandlerErrorAttribute : HandleErrorAttribute
{
 /// <summary>
 /// 控制器方法中出現(xiàn)異常,會調(diào)用該方法捕獲異常
 /// </summary>
 /// <param name="context">提供使用</param>
 public override void OnException(ExceptionContext context)
 {
 WriteLog(context);
 base.OnException(context);
 context.ExceptionHandled = true;
 if (context.Exception is UserFriendlyException)
 {
 context.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
 context.Result = new ContentResult { Content = new AjaxResult { type = ResultType.error, message = context.Exception.Message }.ToJson() };
 }
 else if (context.Exception is NoAuthorizeException)
 {
 context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
 if (!context.HttpContext.Request.IsAjaxRequest())
 {
 context.HttpContext.Response.RedirectToRoute("Default", new { controller = "Error", action = "Error401", errorUrl = context.HttpContext.Request.RawUrl });
 }
 else
 {
 context.Result = new ContentResult { Content = context.HttpContext.Request.RawUrl };
 }
 }
 else
 {
 context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
 ExceptionMessage error = new ExceptionMessage(context.Exception);
 var s = error.ToJson();
 if (!context.HttpContext.Request.IsAjaxRequest())
 {
  context.HttpContext.Response.RedirectToRoute("Default", new { controller = "Error", action = "Error500", data = WebHelper.UrlEncode(s) });
 }
 else
 {
  context.Result = new ContentResult { Content = WebHelper.UrlEncode(s) };
 }
 }
 }
 
 /// <summary>
 /// 寫入日志(log4net)
 /// </summary>
 /// <param name="context">提供使用</param>
 private void WriteLog(ExceptionContext context)
 {
 if (context == null)
 return;
 if (context.Exception is NoAuthorizeException || context.Exception is UserFriendlyException)
 {
 //友好錯誤提示,未授權(quán)錯誤提示,記錄警告日志
 LogHelper.Warn(context.Exception.Message);
 }
 else
 {
 //異常錯誤,
 LogHelper.Error(context.Exception);
 
 ////TODO :寫入錯誤日志到數(shù)據(jù)庫
 }
 }
}

MVC 過濾器全局注冊異常攔截:

public class FilterConfig
 {
 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
 {
 filters.Add(new HandlerErrorAttribute());
 }
 }

我們看到,context.Exception 分為3種:UserFriendlyException,NoAuthorizeException 或 Exception;UserFriendlyException 是指友好異常,前端友好提示錯誤信息。NoAuthorizeException 為401未授權(quán)異常,當(dāng)頁面未被授權(quán)訪問時,返回該異常,并攜帶有未授權(quán)的路徑地址。其他異常統(tǒng)一返回500錯誤,并攜帶異常信息。

三、異常處理 

1.401 未授權(quán)錯誤

異常定義代碼:

/// <summary>
/// 沒有被授權(quán)的異常
/// </summary>
public class NoAuthorizeException : Exception
{
 public NoAuthorizeException(string message)
 : base(message)
 {
 }
}

拋出異常代碼:

throw new NoAuthorizeException("未授權(quán)");

前端UI效果:

2.404 未找到頁面錯誤

MVC的404異常處理,有幾種方式,我們采用了在Global.asax全局請求函數(shù)中處理, 請查看以下代碼

protected void Application_EndRequest()
 {
 if (Context.Response.StatusCode == 404)
 {
 bool isAjax = new HttpRequestWrapper(Context.Request).IsAjaxRequest();
 if (isAjax)
 {
  Response.Clear();
  Response.Write(Context.Request.RawUrl);
 }
 else
 {
  Response.RedirectToRoute("Default", new { controller = "Error", action = "Error404", errorUrl = Context.Request.RawUrl });
 }
 }
 }

前端UI效果:

3.500服務(wù)器內(nèi)部錯誤 

500異常錯誤拋出的異常信息對象定義:

/// <summary>
/// 異常錯誤信息
/// </summary>
[Serializable]
public class ExceptionMessage
{
 public ExceptionMessage()
 {
 }
 
 /// <summary>
 /// 構(gòu)造函數(shù)
 /// 默認(rèn)顯示異常頁面
 /// </summary>
 /// <param name="ex">異常對象</param>
 public ExceptionMessage(Exception ex)
 :this(ex, true)
 {
 
 }
 /// <summary>
 /// 構(gòu)造函數(shù)
 /// </summary>
 /// <param name="ex">異常對象</param>
 /// <param name="isShowException">是否顯示異常頁面</param>
 public ExceptionMessage(Exception ex, bool isShowException)
 {
 MsgType = ex.GetType().Name;
 Message = ex.InnerException != null ? ex.InnerException.Message : ex.Message;
 StackTrace = ex.StackTrace.Length > 300 ? ex.StackTrace.Substring(0, 300) : ex.StackTrace;
 Source = ex.Source;
 Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
 Assembly = ex.TargetSite.Module.Assembly.FullName;
 Method = ex.TargetSite.Name;
 
 ShowException = isShowException;
 var request = HttpContext.Current.Request;
 IP = Net.Ip;
 UserAgent = request.UserAgent;
 Path = request.Path;
 HttpMethod = request.HttpMethod;
 }
 /// <summary>
 /// 消息類型
 /// </summary>
 public string MsgType { get; set; }
 
 /// <summary>
 /// 消息內(nèi)容
 /// </summary>
 public string Message { get; set; }
 
 /// <summary>
 /// 請求路徑
 /// </summary>
 public string Path { get; set; }
 
 /// <summary>
 /// 程序集名稱
 /// </summary>
 public string Assembly { get; set; }
 
 /// <summary>
 /// 異常參數(shù)
 /// </summary>
 public string ActionArguments { get; set; }
 
 /// <summary>
 /// 請求類型
 /// </summary>
 public string HttpMethod { get; set; }
 
 /// <summary>
 /// 異常堆棧
 /// </summary>
 public string StackTrace { get; set; }
 
 /// <summary>
 /// 異常源
 /// </summary>
 public string Source { get; set; }
 
 /// <summary>
 /// 服務(wù)器IP 端口
 /// </summary>
 public string IP { get; set; }
 
 /// <summary>
 /// 客戶端瀏覽器標(biāo)識
 /// </summary>
 public string UserAgent { get; set; }
 
 
 /// <summary>
 /// 是否顯示異常界面
 /// </summary>
 public bool ShowException { get; set; }
 
 /// <summary>
 /// 異常發(fā)生時間
 /// </summary>
 public string Time { get; set; }
 
 /// <summary>
 /// 異常發(fā)生方法
 /// </summary>
 public string Method { get; set; }
}

拋出異常代碼:

throw new Exception("出錯了");

前端UI效果:

4. UserFriendlyException 友好異常

異常定義代碼:

/// <summary>
/// 用戶友好異常
/// </summary>
public class UserFriendlyException : Exception
{
 public UserFriendlyException(string message)
 : base(message)
 {
 }
}

在異常攔截關(guān)鍵代碼中,我們發(fā)現(xiàn)友好異常(UserFriendlyException)其實是返回了一個結(jié)果對象AjaxResult,

AjaxResult對象的定義:

/// <summary>
 /// 表示Ajax操作結(jié)果
 /// </summary>
 public class AjaxResult
 {
 /// <summary>
 /// 獲取 Ajax操作結(jié)果類型
 /// </summary>
 public ResultType type { get; set; }
 
 /// <summary>
 /// 獲取 Ajax操作結(jié)果編碼
 /// </summary>
 public int errorcode { get; set; }
 
 /// <summary>
 /// 獲取 消息內(nèi)容
 /// </summary>
 public string message { get; set; }
 
 /// <summary>
 /// 獲取 返回數(shù)據(jù)
 /// </summary>
 public object resultdata { get; set; }
 }
 /// <summary>
 /// 表示 ajax 操作結(jié)果類型的枚舉
 /// </summary>
 public enum ResultType
 {
 /// <summary>
 /// 消息結(jié)果類型
 /// </summary>
 info = 0,
 
 /// <summary>
 /// 成功結(jié)果類型
 /// </summary>
 success = 1,
 
 /// <summary>
 /// 警告結(jié)果類型
 /// </summary>
 warning = 2,
 
 /// <summary>
 /// 異常結(jié)果類型
 /// </summary>
 error = 3
 }

四、Ajax請求異常時處理

在異常攔截的關(guān)鍵代碼中,我們有看到,如果是ajax請求時,是執(zhí)行不同的邏輯,這是因為ajax的請求,不能直接通過MVC的路由跳轉(zhuǎn),在請求時必須返回結(jié)果內(nèi)容

然后在前端ajax的方法中,統(tǒng)一處理返回的錯誤,以下是我們項目中用到的ajax封裝,對異常錯誤,進(jìn)行了統(tǒng)一處理。

(function ($) {
 "use strict";
 
 $.httpCode = {
 success: "1",
 fail: "3",
 };
 // http 通信異常的時候調(diào)用此方法
 $.httpErrorLog = function (msg) {
 console.log('=====>' + new Date().getTime() + '<=====');
 console.log(msg);
 };
 
 // ajax請求錯誤處理
 $.httpError = function (xhr, textStatus, errorThrown) {
 
 if (xhr.status == 401) {
  location.href = "/Error/Error401?errorUrl=" + xhr.responseText;
 }
 
 if (xhr.status == 404) {
  location.href = "/Error/Error404?errorUrl=" + xhr.responseText;
 }
 
 if (xhr.status == 500) {
  location.href = "/Error/Error500?data=" + xhr.responseText;
 }
 };
 
 /* get請求方法(異步):
 * url地址, param參數(shù), callback回調(diào)函數(shù) beforeSend 請求之前回調(diào)函數(shù), complete 請求完成之后回調(diào)函數(shù)
 * 考慮到get請求一般將參數(shù)與url拼接一起傳遞,所以將param參數(shù)放置最后
 * 返回AjaxResult結(jié)果對象
 */
 $.httpAsyncGet = function (url, callback, beforeSend, complete, param) {
 $.ajax({
  url: url,
  data: param,
  type: "GET",
  dataType: "json",
  async: true,
  cache: false,
  success: function (data) {
  if ($.isFunction(callback)) callback(data);
  },
  error: function (XMLHttpRequest, textStatus, errorThrown) {
  $.httpError(XMLHttpRequest, textStatus, errorThrown);
  },
  beforeSend: function () {
  if (!!beforeSend) beforeSend();
  },
  complete: function () {
  if (!!complete) complete();
  }
 });
 };
 
 /* get請求方法(同步):
 * url地址,param參數(shù)
 * 返回實體數(shù)據(jù)對象
 */
 $.httpGet = function (url, param) {
 var res = {};
 $.ajax({
  url: url,
  data: param,
  type: "GET",
  dataType: "json",
  async: false,
  cache: false,
  success: function (data) {
  res = data;
  },
  error: function (XMLHttpRequest, textStatus, errorThrown) {
  $.httpError(XMLHttpRequest, textStatus, errorThrown);
  },
 });
 return res;
 };
 
 /* post請求方法(異步):
 * url地址, param參數(shù), callback回調(diào)函數(shù) beforeSend 請求之前回調(diào)函數(shù), complete 請求完成之后回調(diào)函數(shù)
 * 返回AjaxResult結(jié)果對象
 */
 $.httpAsyncPost = function (url, param, callback, beforeSend, complete) {
 $.ajax({
  url: url,
  data: param,
  type: "POST",
  dataType: "json",
  async: true,
  cache: false,
  success: function (data) {
  if ($.isFunction(callback)) callback(data);
  },
  error: function (XMLHttpRequest, textStatus, errorThrown) {
  $.httpError(XMLHttpRequest, textStatus, errorThrown);
  },
  beforeSend: function () {
  if (!!beforeSend) beforeSend();
  },
  complete: function () {
  if (!!complete) complete();
  }
 });
 };
 
 /* post請求方法(同步):
 * url地址,param參數(shù), callback回調(diào)函數(shù)
 * 返回實體數(shù)據(jù)對象
 */
 $.httpPost = function (url, param, callback) {
 $.ajax({
  url: url,
  data: param,
  type: "POST",
  dataType: "json",
  async: false,
  cache: false,
  success: function (data) {
  if ($.isFunction(callback)) callback(data);
  },
  error: function (XMLHttpRequest, textStatus, errorThrown) {
  $.httpError(XMLHttpRequest, textStatus, errorThrown);
  },
 });
 },
 
 /* ajax異步封裝:
 * type 請求類型, url地址, param參數(shù), callback回調(diào)函數(shù)
 * 返回實體數(shù)據(jù)對象
 */
 $.httpAsync = function (type, url, param, callback) {
 $.ajax({
  url: url,
  data: param,
  type: type,
  dataType: "json",
  async: true,
  cache: false,
  success: function (data) {
  if ($.isFunction(callback)) callback(data);
  },
  error: function (XMLHttpRequest, textStatus, errorThrown) {
  $.httpError(XMLHttpRequest, textStatus, errorThrown);
  },
 });
 };
})(jQuery);

五、總結(jié)

至此,我們發(fā)現(xiàn)其實MVC的異常處理,真的很簡單,只需要在過濾器中全局注冊之后,然后重寫OnException的方法,實現(xiàn)邏輯即可。關(guān)鍵是在于項目中Ajax請求,需要用統(tǒng)一的封裝方法。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

最新評論