一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - ASP.NET教程 - ASP.NET MVC中異常Exception攔截的深入理解

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

2020-05-28 14:57沉淀的風(fēng) ASP.NET教程

異常信息的處理在程序中非常重要, 在asp.net mvc中提供異常屬性攔截器進行對異常信息的處理,下面這篇文章主要給大家介紹了關(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)邏輯代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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 過濾器全局注冊異常攔截:

?
1
2
3
4
5
6
7
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)錯誤

異常定義代碼:

?
1
2
3
4
5
6
7
8
9
10
/// <summary>
/// 沒有被授權(quán)的異常
/// </summary>
public class NoAuthorizeException : Exception
{
 public NoAuthorizeException(string message)
 : base(message)
 {
 }
}

拋出異常代碼:

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

前端UI效果:

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

2.404 未找到頁面錯誤

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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效果:

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/// <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; }
}

拋出異常代碼:

?
1
throw new Exception("出錯了");

前端UI效果:

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

4. UserFriendlyException 友好異常

異常定義代碼:

?
1
2
3
4
5
6
7
8
9
10
/// <summary>
/// 用戶友好異常
/// </summary>
public class UserFriendlyException : Exception
{
 public UserFriendlyException(string message)
 : base(message)
 {
 }
}

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

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

AjaxResult對象的定義:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/// <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)容

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
(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í)價值,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。

原文鏈接:https://www.cnblogs.com/xyb0226/p/9250334.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久成人精品免费播放 | 欧美日本一道高清二区三区 | 亚洲激情一区 | 免费片在线观看 | 亚洲国产中文字幕在线视频综合 | 久久囯产精品777蜜桃传媒 | 亚洲成a人不卡在线观看 | 韩国理论片最新第一页 | 春意影院午夜爽爽爽免费 | 村上里沙40分钟在线观看 | 91香蕉国产在线观看人员 | 欧美黑人成人免费全部 | 国产精品一级香蕉一区 | 国产精品刺激好大好爽视频 | 91免费播放人人爽人人快乐 | 国产综合成人久久大片91 | 成在线人免费 | 香港三级血恋3 | 免费观看成年肉动漫网站 | 四虎comwww最新地址 | 性欧美xxxxx护士另类 | 翁息肉小说老扒 | 欧美人做人爱a全程免费 | 999导航| 亚洲热在线观看 | 99视频在线免费 | 精品99在线观看 | 被教官揉了一晚上的奶小说 | 体检小说| 美女扒开粉嫩尿口漫画 | 欧美性f | 色综合色狠狠天天久久婷婷基地 | 亚洲 另类 欧美 变态屎尿 | 女子校生下媚药在线观看 | 久草在线精彩免费视频 | 欧美日韩一区二区三区在线播放 | 欧美午夜视频一区二区三区 | 337p大尺度啪啪人体午夜2020 | 美女免费观看一区二区三区 | 极品 女神校花 露脸91 | 欧美日韩亚洲高清不卡一区二区三区 |