前言:上篇c#進(jìn)階系列——webapi接口傳參不再困惑:傳參詳解介紹了webapi參數(shù)的傳遞,這篇來看看webapi里面異常的處理。關(guān)于異常處理,作為程序員的我們肯定不陌生,記得在介紹 aop的時(shí)候,我們講過通過aop可以統(tǒng)一截獲異常。那么在我們的webapi里面一般是怎么處理異常的呢,今天這一篇,博主帶著大家一起來實(shí)踐下webapi的異常處理。
為什么說是實(shí)踐?因?yàn)樵趆ttp://www.asp.net里面已經(jīng)明確給出webapi的異常處理機(jī)制。光有理論還不夠,今天我們還是來試一把。通過實(shí)踐,我們可能發(fā)現(xiàn)一些更詳盡的用法。
一、使用異常篩選器捕獲所有異常
我們知道,一般情況下,webapi作為服務(wù)使用,每次客戶端發(fā)送http請(qǐng)求到我們的webapi服務(wù)里面,服務(wù)端得到結(jié)果輸出response到客戶端。這個(gè)過程中,一旦服務(wù)端發(fā)生異常,會(huì)統(tǒng)一向客戶端返回500的錯(cuò)誤。
1
2
3
4
5
|
[httpget] public string getallchargingdata([fromuri]tb_charging obj) { throw new notimplementedexception( "方法不被支持" ); } |
我們來看看http請(qǐng)求
而有些時(shí)候,我們客戶端需要得到更加精確的錯(cuò)誤碼來判斷異常類型,怎么辦呢?
記得在介紹aop的時(shí)候,我們介紹過mvc里面的iexceptionfilter接口,這個(gè)接口用于定義異常篩選器所需的方法,在webapi里面,也有這么一個(gè)異常篩選器,下面我們通過一個(gè)實(shí)例來看看具體如何實(shí)現(xiàn)。
首先在app_start里面新建一個(gè)類webapiexceptionfilterattribute.cs,繼承exceptionfilterattribute,重寫onexception方法
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
|
public class webapiexceptionfilterattribute : exceptionfilterattribute { //重寫基類的異常處理方法 public override void onexception(httpactionexecutedcontext actionexecutedcontext) { //1.異常日志記錄(正式項(xiàng)目里面一般是用log4net記錄異常日志) console.writeline(datetime.now.tostring( "yyyy-mm-dd hh:mm:ss" ) + "——" + actionexecutedcontext.exception.gettype().tostring() + ":" + actionexecutedcontext.exception.message + "——堆棧信息:" + actionexecutedcontext.exception.stacktrace); //2.返回調(diào)用方具體的異常信息 if (actionexecutedcontext.exception is notimplementedexception) { actionexecutedcontext.response = new httpresponsemessage(httpstatuscode.notimplemented); } else if (actionexecutedcontext.exception is timeoutexception) { actionexecutedcontext.response = new httpresponsemessage(httpstatuscode.requesttimeout); } //.....這里可以根據(jù)項(xiàng)目需要返回到客戶端特定的狀態(tài)碼。如果找不到相應(yīng)的異常,統(tǒng)一返回服務(wù)端錯(cuò)誤500 else { actionexecutedcontext.response = new httpresponsemessage(httpstatuscode.internalservererror); } base .onexception(actionexecutedcontext); } } |
代碼解析:通過判斷異常的具體類型,向客戶端返回不同的http狀態(tài)碼,示例里面寫了兩個(gè),可以根據(jù)項(xiàng)目的實(shí)際情況加一些特定的我們想要捕獲的異常,然后將對(duì)應(yīng)的狀態(tài)碼寫入http請(qǐng)求的response里面,對(duì)于一些我們無法判斷類型的異常,統(tǒng)一返回服務(wù)端錯(cuò)誤500。關(guān)于http的狀態(tài)碼,framework里面定義了一些常見的類型,我們大概看看:
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
#region 程序集 system.dll, v4.0.0.0 // c:\program files (x86)\reference assemblies\microsoft\framework\.netframework\v4.5\system.dll #endregion using system; namespace system.net { // 摘要: // 包含為 http 定義的狀態(tài)代碼的值。 public enum httpstatuscode { // 摘要: // 等效于 http 狀態(tài) 100。 system.net.httpstatuscode.continue 指示客戶端可能繼續(xù)其請(qǐng)求。 continue = 100, // // 摘要: // 等效于 http 狀態(tài) 101。 system.net.httpstatuscode.switchingprotocols 指示正在更改協(xié)議版本或協(xié)議。 switchingprotocols = 101, // // 摘要: // 等效于 http 狀態(tài) 200。 system.net.httpstatuscode.ok 指示請(qǐng)求成功,且請(qǐng)求的信息包含在響應(yīng)中。 這是最常接收的狀態(tài)代碼。 ok = 200, // // 摘要: // 等效于 http 狀態(tài) 201。 system.net.httpstatuscode.created 指示請(qǐng)求導(dǎo)致在響應(yīng)被發(fā)送前創(chuàng)建新資源。 created = 201, // // 摘要: // 等效于 http 狀態(tài) 202。 system.net.httpstatuscode.accepted 指示請(qǐng)求已被接受做進(jìn)一步處理。 accepted = 202, // // 摘要: // 等效于 http 狀態(tài) 203。 system.net.httpstatuscode.nonauthoritativeinformation 指示返回的元信息來自緩存副本而不是原始服務(wù)器,因此可能不正確。 nonauthoritativeinformation = 203, // // 摘要: // 等效于 http 狀態(tài) 204。 system.net.httpstatuscode.nocontent 指示已成功處理請(qǐng)求并且響應(yīng)已被設(shè)定為無內(nèi)容。 nocontent = 204, // // 摘要: // 等效于 http 狀態(tài) 205。 system.net.httpstatuscode.resetcontent 指示客戶端應(yīng)重置(或重新加載)當(dāng)前資源。 resetcontent = 205, // // 摘要: // 等效于 http 狀態(tài) 206。 system.net.httpstatuscode.partialcontent 指示響應(yīng)是包括字節(jié)范圍的 get // 請(qǐng)求所請(qǐng)求的部分響應(yīng)。 partialcontent = 206, // // 摘要: // 等效于 http 狀態(tài) 300。 system.net.httpstatuscode.multiplechoices 指示請(qǐng)求的信息有多種表示形式。 // 默認(rèn)操作是將此狀態(tài)視為重定向,并遵循與此響應(yīng)關(guān)聯(lián)的 location 標(biāo)頭的內(nèi)容。 multiplechoices = 300, // // 摘要: // 等效于 http 狀態(tài) 300。 system.net.httpstatuscode.ambiguous 指示請(qǐng)求的信息有多種表示形式。 默認(rèn)操作是將此狀態(tài)視為重定向,并遵循與此響應(yīng)關(guān)聯(lián)的 // location 標(biāo)頭的內(nèi)容。 ambiguous = 300, // // 摘要: // 等效于 http 狀態(tài) 301。 system.net.httpstatuscode.movedpermanently 指示請(qǐng)求的信息已移到 location // 頭中指定的 uri 處。 接收到此狀態(tài)時(shí)的默認(rèn)操作為遵循與響應(yīng)關(guān)聯(lián)的 location 頭。 movedpermanently = 301, // // 摘要: // 等效于 http 狀態(tài) 301。 system.net.httpstatuscode.moved 指示請(qǐng)求的信息已移到 location 頭中指定的 // uri 處。 接收到此狀態(tài)時(shí)的默認(rèn)操作為遵循與響應(yīng)關(guān)聯(lián)的 location 頭。 原始請(qǐng)求方法為 post 時(shí),重定向的請(qǐng)求將使用 get 方法。 moved = 301, // // 摘要: // 等效于 http 狀態(tài) 302。 system.net.httpstatuscode.found 指示請(qǐng)求的信息位于 location 頭中指定的 // uri 處。 接收到此狀態(tài)時(shí)的默認(rèn)操作為遵循與響應(yīng)關(guān)聯(lián)的 location 頭。 原始請(qǐng)求方法為 post 時(shí),重定向的請(qǐng)求將使用 get 方法。 found = 302, // // 摘要: // 等效于 http 狀態(tài) 302。 system.net.httpstatuscode.redirect 指示請(qǐng)求的信息位于 location 頭中指定的 // uri 處。 接收到此狀態(tài)時(shí)的默認(rèn)操作為遵循與響應(yīng)關(guān)聯(lián)的 location 頭。 原始請(qǐng)求方法為 post 時(shí),重定向的請(qǐng)求將使用 get 方法。 redirect = 302, // // 摘要: // 等效于 http 狀態(tài) 303。 作為 post 的結(jié)果,system.net.httpstatuscode.seeother 將客戶端自動(dòng)重定向到 // location 頭中指定的 uri。 用 get 生成對(duì) location 標(biāo)頭所指定的資源的請(qǐng)求。 seeother = 303, // // 摘要: // 等效于 http 狀態(tài) 303。 作為 post 的結(jié)果,system.net.httpstatuscode.redirectmethod 將客戶端自動(dòng)重定向到 // location 頭中指定的 uri。 用 get 生成對(duì) location 標(biāo)頭所指定的資源的請(qǐng)求。 redirectmethod = 303, // // 摘要: // 等效于 http 狀態(tài) 304。 system.net.httpstatuscode.notmodified 指示客戶端的緩存副本是最新的。 未傳輸此資源的內(nèi)容。 notmodified = 304, // // 摘要: // 等效于 http 狀態(tài) 305。 system.net.httpstatuscode.useproxy 指示請(qǐng)求應(yīng)使用位于 location 頭中指定的 // uri 的代理服務(wù)器。 useproxy = 305, // // 摘要: // 等效于 http 狀態(tài) 306。 system.net.httpstatuscode.unused 是未完全指定的 http/1.1 規(guī)范的建議擴(kuò)展。 unused = 306, // // 摘要: // 等效于 http 狀態(tài) 307。 system.net.httpstatuscode.redirectkeepverb 指示請(qǐng)求信息位于 location // 頭中指定的 uri 處。 接收到此狀態(tài)時(shí)的默認(rèn)操作為遵循與響應(yīng)關(guān)聯(lián)的 location 頭。 原始請(qǐng)求方法為 post 時(shí),重定向的請(qǐng)求還將使用 // post 方法。 redirectkeepverb = 307, // // 摘要: // 等效于 http 狀態(tài) 307。 system.net.httpstatuscode.temporaryredirect 指示請(qǐng)求信息位于 location // 頭中指定的 uri 處。 接收到此狀態(tài)時(shí)的默認(rèn)操作為遵循與響應(yīng)關(guān)聯(lián)的 location 頭。 原始請(qǐng)求方法為 post 時(shí),重定向的請(qǐng)求還將使用 // post 方法。 temporaryredirect = 307, // // 摘要: // 等效于 http 狀態(tài) 400。 system.net.httpstatuscode.badrequest 指示服務(wù)器未能識(shí)別請(qǐng)求。 如果沒有其他適用的錯(cuò)誤,或者不知道準(zhǔn)確的錯(cuò)誤或錯(cuò)誤沒有自己的錯(cuò)誤代碼,則發(fā)送 // system.net.httpstatuscode.badrequest。 badrequest = 400, // // 摘要: // 等效于 http 狀態(tài) 401。 system.net.httpstatuscode.unauthorized 指示請(qǐng)求的資源要求身份驗(yàn)證。 www-authenticate // 頭包含如何執(zhí)行身份驗(yàn)證的詳細(xì)信息。 unauthorized = 401, // // 摘要: // 等效于 http 狀態(tài) 402。 保留 system.net.httpstatuscode.paymentrequired 以供將來使用。 paymentrequired = 402, // // 摘要: // 等效于 http 狀態(tài) 403。 system.net.httpstatuscode.forbidden 指示服務(wù)器拒絕滿足請(qǐng)求。 forbidden = 403, // // 摘要: // 等效于 http 狀態(tài) 404。 system.net.httpstatuscode.notfound 指示請(qǐng)求的資源不在服務(wù)器上。 notfound = 404, // // 摘要: // 等效于 http 狀態(tài) 405。 system.net.httpstatuscode.methodnotallowed 指示請(qǐng)求的資源上不允許請(qǐng)求方法(post // 或 get)。 methodnotallowed = 405, // // 摘要: // 等效于 http 狀態(tài) 406。 system.net.httpstatuscode.notacceptable 指示客戶端已用 accept 頭指示將不接受資源的任何可用表示形式。 notacceptable = 406, // // 摘要: // 等效于 http 狀態(tài) 407。 system.net.httpstatuscode.proxyauthenticationrequired 指示請(qǐng)求的代理要求身份驗(yàn)證。 // proxy-authenticate 頭包含如何執(zhí)行身份驗(yàn)證的詳細(xì)信息。 proxyauthenticationrequired = 407, // // 摘要: // 等效于 http 狀態(tài) 408。 system.net.httpstatuscode.requesttimeout 指示客戶端沒有在服務(wù)器期望請(qǐng)求的時(shí)間內(nèi)發(fā)送請(qǐng)求。 requesttimeout = 408, // // 摘要: // 等效于 http 狀態(tài) 409。 system.net.httpstatuscode.conflict 指示由于服務(wù)器上的沖突而未能執(zhí)行請(qǐng)求。 conflict = 409, // // 摘要: // 等效于 http 狀態(tài) 410。 system.net.httpstatuscode.gone 指示請(qǐng)求的資源不再可用。 gone = 410, // // 摘要: // 等效于 http 狀態(tài) 411。 system.net.httpstatuscode.lengthrequired 指示缺少必需的 content-length // 頭。 lengthrequired = 411, // // 摘要: // 等效于 http 狀態(tài) 412。 system.net.httpstatuscode.preconditionfailed 指示為此請(qǐng)求設(shè)置的條件失敗,且無法執(zhí)行此請(qǐng)求。 // 條件是用條件請(qǐng)求標(biāo)頭(如 if-match、if-none-match 或 if-unmodified-since)設(shè)置的。 preconditionfailed = 412, // // 摘要: // 等效于 http 狀態(tài) 413。 system.net.httpstatuscode.requestentitytoolarge 指示請(qǐng)求太大,服務(wù)器無法處理。 requestentitytoolarge = 413, // // 摘要: // 等效于 http 狀態(tài) 414。 system.net.httpstatuscode.requesturitoolong 指示 uri 太長(zhǎng)。 requesturitoolong = 414, // // 摘要: // 等效于 http 狀態(tài) 415。 system.net.httpstatuscode.unsupportedmediatype 指示請(qǐng)求是不支持的類型。 unsupportedmediatype = 415, // // 摘要: // 等效于 http 狀態(tài) 416。 system.net.httpstatuscode.requestedrangenotsatisfiable 指示無法返回從資源請(qǐng)求的數(shù)據(jù)范圍,因?yàn)榉秶拈_頭在資源的開頭之前,或因?yàn)榉秶慕Y(jié)尾在資源的結(jié)尾之后。 requestedrangenotsatisfiable = 416, // // 摘要: // 等效于 http 狀態(tài) 417。 system.net.httpstatuscode.expectationfailed 指示服務(wù)器未能符合 expect // 頭中給定的預(yù)期值。 expectationfailed = 417, // upgraderequired = 426, // // 摘要: // 等效于 http 狀態(tài) 500。 system.net.httpstatuscode.internalservererror 指示服務(wù)器上發(fā)生了一般錯(cuò)誤。 internalservererror = 500, // // 摘要: // 等效于 http 狀態(tài) 501。 system.net.httpstatuscode.notimplemented 指示服務(wù)器不支持請(qǐng)求的函數(shù)。 notimplemented = 501, // // 摘要: // 等效于 http 狀態(tài) 502。 system.net.httpstatuscode.badgateway 指示中間代理服務(wù)器從另一代理或原始服務(wù)器接收到錯(cuò)誤響應(yīng)。 badgateway = 502, // // 摘要: // 等效于 http 狀態(tài) 503。 system.net.httpstatuscode.serviceunavailable 指示服務(wù)器暫時(shí)不可用,通常是由于過多加載或維護(hù)。 serviceunavailable = 503, // // 摘要: // 等效于 http 狀態(tài) 504。 system.net.httpstatuscode.gatewaytimeout 指示中間代理服務(wù)器在等待來自另一個(gè)代理或原始服務(wù)器的響應(yīng)時(shí)已超時(shí)。 gatewaytimeout = 504, // // 摘要: // 等效于 http 狀態(tài) 505。 system.net.httpstatuscode.httpversionnotsupported 指示服務(wù)器不支持請(qǐng)求的 // http 版本。 httpversionnotsupported = 505, } } |
定義好了異常處理方法,剩下的就是如何使用了。可以根據(jù)實(shí)際情況,在不同級(jí)別使用統(tǒng)一的異常處理機(jī)制。
1、接口級(jí)別
1
2
3
4
5
6
|
[webapiexceptionfilter] [httpget] public string getallchargingdata([fromuri]tb_charging obj) { throw new notimplementedexception( "方法不被支持" ); } |
執(zhí)行到異常后,會(huì)先進(jìn)到onexception方法:
執(zhí)行完成之后瀏覽器查看:
如果需要,甚至可以向status code里面寫入自定義的描述信息,并且還可以向我們的response的content里面寫入我們想要的信息。我們稍微改下onexception方法:
1
2
3
4
5
6
7
|
if (actionexecutedcontext.exception is notimplementedexception) { var oresponse = new httpresponsemessage(httpstatuscode.notimplemented); oresponse.content = new stringcontent( "方法不被支持" ); oresponse.reasonphrase = "this func is not supported" ; actionexecutedcontext.response = oresponse; } |
看看reasonphrase描述信息
看看response的描述信息
2、控制器級(jí)別
如果想要某一個(gè)或者多個(gè)控制器里面的所有接口都使用異常過濾,直接在控制器上面標(biāo)注特性即可。
某一個(gè)控制器上面啟用異常過濾
1
2
3
4
5
6
7
8
9
10
|
[webapiexceptionfilter] public class chargingcontroller : baseapicontroller { #region get [httpget] public string getallchargingdata([fromuri]tb_charging obj) { throw new notimplementedexception( "方法不被支持" ); } } |
多個(gè)控制器上面同時(shí)啟用異常過濾
1
2
3
4
|
[webapiexceptionfilter] public class baseapicontroller : apicontroller { } |
1
2
3
4
5
6
7
8
9
|
public class chargingcontroller : baseapicontroller { #region get [httpget] public string getallchargingdata([fromuri]tb_charging obj) { throw new notimplementedexception( "方法不被支持" ); } } |
這樣,所有繼承baseapicontroller的子類都會(huì)啟用異常過濾。
3、全局配置
如果需要對(duì)整個(gè)應(yīng)用程序都啟用異常過濾,則需要做如下兩步:
1、在global.asax全局配置里面添加globalconfiguration.configuration.filters.add(new webapiexceptionfilterattribute());
這一句,如下:
1
2
3
4
5
6
7
8
|
void application_start( object sender, eventargs e) { // 在應(yīng)用程序啟動(dòng)時(shí)運(yùn)行的代碼 arearegistration.registerallareas(); globalconfiguration.configure(webapiconfig.register); routeconfig.registerroutes(routetable.routes); globalconfiguration.configuration.filters.add( new webapiexceptionfilterattribute()); } |
2、在webapiconfig.cs文件的register方法里面添加 config.filters.add(new webapiexceptionfilterattribute());
這一句,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public static void register(httpconfiguration config) { //跨域配置 config.enablecors( new enablecorsattribute( "*" , "*" , "*" )); // web api 路由 config.maphttpattributeroutes(); routetable.routes.maphttproute( name: "defaultapi" , routetemplate: "api/{controller}/{action}/{id}" , defaults: new { id = routeparameter.optional } ).routehandler = new sessioncontrollerroutehandler(); config.filters.add( new webapiexceptionfilterattribute()); } |
二、httpresponseexception自定義異常信息
上面說的是全局的異常捕獲以及處理方式,在某些情況下,我們希望以異常的方式向客戶端發(fā)送相關(guān)信息,可能就需要用到我們的httpresponseexception。比如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
[httpget] public tb_charging getbyid( string id) { //從后臺(tái)查詢實(shí)體 var omodel = server.find(id); if (omodel == null ) { var resp = new httpresponsemessage(httpstatuscode.notfound) { content = new stringcontent( string .format( "沒有找到id={0}的對(duì)象" , id)), reasonphrase = "object is not found" }; throw new httpresponseexception(resp); } return omodel; } |
執(zhí)行之后瀏覽器里面查看結(jié)果:
代碼釋疑:細(xì)心的朋友可能,發(fā)現(xiàn)了,這里既使用了httpresponsemessage,又使用了httpresponseexception,那么,像這種可控的異常,我們是否可以直接以httpresponsemessage的形式直接返回到客戶端而不用拋出異常呢?這里就要談?wù)勥@兩個(gè)對(duì)象的區(qū)別了,博主的理解是httpresonsemessage對(duì)象用來響應(yīng)訊息并包含狀態(tài)碼及數(shù)據(jù)內(nèi)容,httpresponseexception對(duì)象用來向客戶端返回包含錯(cuò)誤訊息的異常。
在網(wǎng)上看到一篇文章這樣描述兩者的區(qū)別:當(dāng)呼叫 web api 服務(wù)時(shí)發(fā)生了與預(yù)期上不同的錯(cuò)誤時(shí),理當(dāng)應(yīng)該中止程序返回錯(cuò)誤訊息,這時(shí)對(duì)于錯(cuò)誤的返回就該使用 httpresponseexception,而使用 httpresponsemessage 則是代表著當(dāng)客戶端發(fā)送了一個(gè)工作請(qǐng)求而 web api 正確的完成了這個(gè)工作,就能夠使用 httpresponsemessage 返回一個(gè) 201 的訊息,所以 httpresponsemessage 與 httpresponseexception 在使用上根本的目標(biāo)就是不同的,用 httpresponsemessage 去返回一個(gè)例外錯(cuò)誤也會(huì)讓程序結(jié)構(gòu)難以辨別且不夠清晰。
三、返回httperror
httperror對(duì)象提供一致的方法來響應(yīng)正文中返回錯(cuò)誤的信息。準(zhǔn)確來說,httperror并不是一個(gè)異常,只是用來包裝錯(cuò)誤信息的一個(gè)對(duì)象。其實(shí)在某一定的程度上,httperror和httpresponsemessage使用比較相似,二者都可以向客戶端返回http狀態(tài)碼和錯(cuò)誤訊息,并且都可以包含在httpresponseexception對(duì)象中發(fā)回到客戶端。但是,一般情況下,httperror只有在向客戶端返回錯(cuò)誤訊息的時(shí)候才會(huì)使用,而httpresponsemessage對(duì)象既可以返回錯(cuò)誤訊息,也可返回請(qǐng)求正確的消息。其實(shí)關(guān)于httperror沒什么特別好講的,我們來看一個(gè)例子就能明白:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public httpresponsemessage update(dynamic obj) { tb_product omodel = null ; try { var id = convert.tostring(obj.id); omodel = newtonsoft.json.jsonconvert.deserializeobject<tb_product>(convert.tostring(obj.datamodel)); //...復(fù)雜的業(yè)務(wù)邏輯 } catch (exception ex) { return request.createerrorresponse(httpstatuscode.badrequest, ex.message); } return request.createresponse<tb_product>(httpstatuscode.ok, omodel); } |
假如現(xiàn)在在執(zhí)行try里面復(fù)雜業(yè)務(wù)邏輯的時(shí)候發(fā)生了異常,我們捕獲到了異常然后向客戶端返回httperror對(duì)象,這個(gè)對(duì)象里面包含我們自定義的錯(cuò)誤訊息,如果正常則返回httpresponsemessage對(duì)象。
如果請(qǐng)求異常:
如果請(qǐng)求正常
四、總結(jié)
以上三種異常的處理方法,可以根據(jù)不同的場(chǎng)景選擇使用。
- 如果項(xiàng)目對(duì)異常處理要求并不高,只需要記錄好異常日志即可,那么使用異常篩選器就能夠搞定
- 如果項(xiàng)目需要對(duì)不同的異常,客戶端做不同的處理。而這個(gè)時(shí)候使用異常篩選器不能詳盡所有的異常,可能使用httpresponseexception對(duì)象是更好的選擇,定義更加精細(xì)的異常和異常描述。
- 對(duì)于何時(shí)使用httperror,又何時(shí)使用httpresponsemessage,可以參考上文三里面用法。
- 當(dāng)然實(shí)際項(xiàng)目中很可能以上兩種或者三種同時(shí)使用。
上文通過一些簡(jiǎn)單的示例介紹了下webapi里面異常的處理機(jī)制,可能不夠深入,但對(duì)于一般項(xiàng)目的異常處理基本夠用。其實(shí)有一點(diǎn)博主還沒有想明白,對(duì)于構(gòu)造函數(shù)里面的異常該如何統(tǒng)一捕獲呢?通過異常篩選器是捕獲不到的,不知道園友們有沒有什么更好的辦法,不吝賜教,感謝感謝!如果本文能幫到你,不妨推薦下,您的推薦是博主繼續(xù)總結(jié)的動(dòng)力!也希望大家多多支持服務(wù)器之家。
原文鏈接:http://www.cnblogs.com/landeanfen/p/5363846.html