ASP.NET Web API之消息[拦截]处理(转)
出處:http://www.cnblogs.com/Leo_wl/p/3238719.html
標(biāo)題相當(dāng)難取,內(nèi)容也許和您想的不一樣,而且網(wǎng)上已經(jīng)有很多這方面的資料了,我不過(guò)是在實(shí)踐過(guò)程中作下記錄。廢話(huà)少說(shuō),直接開(kāi)始。
Exception
當(dāng)服務(wù)端拋出未處理異常時(shí),most exceptions are translated into an HTTP response with status code 500, Internal Server Error.當(dāng)然我們也可以?huà)伋鲆粋€(gè)特殊的異常HttpResponseException,它將被直接寫(xiě)入響應(yīng)流,而不會(huì)被轉(zhuǎn)成500。
public Product GetProduct(int id) {Product item = repository.Get(id);if (item == null){throw new HttpResponseException(HttpStatusCode.NotFound);}return item; }有時(shí)要對(duì)服務(wù)端異常做一封裝,以便對(duì)客戶(hù)端隱藏具體細(xì)節(jié),或者統(tǒng)一格式,那么可創(chuàng)建一繼承自System.Web.Http.Filters.ExceptionFilterAttribute的特性,如下:
public class APIExceptionFilterAttribute : ExceptionFilterAttribute {public override void OnException(HttpActionExecutedContext context){//業(yè)務(wù)異常if (context.Exception is BusinessException){context.Response = new HttpResponseMessage { StatusCode = System.Net.HttpStatusCode.ExpectationFailed };BusinessException exception = (BusinessException)context.Exception;context.Response.Headers.Add("BusinessExceptionCode", exception.Code);context.Response.Headers.Add("BusinessExceptionMessage", exception.Message);}//其它異常else{context.Response = new HttpResponseMessage { StatusCode = System.Net.HttpStatusCode.InternalServerError };}} }然后將該Attribute應(yīng)用到action或controller,或者GlobalConfiguration.Configuration.Filters.Add(new?APIExceptionFilterAttribute());使之應(yīng)用于所有action(If you use the "ASP.NET MVC 4 Web Application" project template to create your project, put your Web API configuration code inside the?WebApiConfig?class, which is located in the App_Start folder:config.Filters.Add(newProductStore.NotImplExceptionFilterAttribute());)。當(dāng)然,在上述代碼中,我們也可以在OnException方法中直接拋出HttpResponseException,效果是一樣的。
Note: Something to have in mind is that the ExceptionFilterAttribute will be ignored if the ApiController action method throws a HttpResponseException;If something goes wrong in the ExceptionFilterAttribute and an exception is thrown that is not of type HttpResponseException, a formatted exception will be thrown with stack trace etc to the client.
如果要返回給客戶(hù)端的不僅僅是一串字符串,比如是json對(duì)象,那么可以使用HttpError這個(gè)類(lèi)。
以上知識(shí)主要來(lái)自Exception Handling in ASP.NET Web API。
ActionFilterAttribute、ApiControllerActionInvoker?
有時(shí)要在action執(zhí)行前后做額外處理,那么ActionFilterAttribute和ApiControllerActionInvoker就派上用場(chǎng)了。比如客戶(hù)端請(qǐng)求發(fā)過(guò)來(lái)的參數(shù)為用戶(hù)令牌字符串token,我們要在action執(zhí)行之前先將其轉(zhuǎn)為action參數(shù)列表中對(duì)應(yīng)的用戶(hù)編號(hào)ID,如下:?
public class TokenProjectorAttribute : ActionFilterAttribute {private string _userid = "userid";public string UserID{get { return _userid; }set { _userid = value; }}public override void OnActionExecuting(HttpActionContext actionContext){if (!actionContext.ActionArguments.ContainsKey(UserID)){//參數(shù)列表中不存在userid,寫(xiě)入日志//……var response = new HttpResponseMessage();response.Content = new StringContent("用戶(hù)信息轉(zhuǎn)換異常.");response.StatusCode = HttpStatusCode.Conflict;//在這里為了不繼續(xù)走流程,要throw出來(lái),才會(huì)立馬返回到客戶(hù)端throw new HttpResponseException(response);}//userid系統(tǒng)賦值actionContext.ActionArguments[UserID] = actionContext.Request.Properties["shumi_userid"];base.OnActionExecuting(actionContext);}public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext){base.OnActionExecuted(actionExecutedContext);} }ActionFilterAttribute如何應(yīng)用到action,和前面的ExceptionFilterAttribute類(lèi)似。
ApiControllerActionInvoker以上述Exception為例:
public class ServerAPIControllerActionInvoker : ApiControllerActionInvoker {public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, CancellationToken cancellationToken){//對(duì)actionContext做一些預(yù)處理//……var result = base.InvokeActionAsync(actionContext, cancellationToken);if (result.Exception != null && result.Exception.GetBaseException() != null){var baseException = result.Exception.GetBaseException();if (baseException is BusinessException){return Task.Run<HttpResponseMessage>(() =>{var response = new HttpResponseMessage(HttpStatusCode.ExpectationFailed);BusinessException exception = (BusinessException)baseException;response.Headers.Add("BusinessExceptionCode", exception.Code);response.Headers.Add("BusinessExceptionMessage", exception.Message);return response;});}else{return Task.Run<HttpResponseMessage>(() => new HttpResponseMessage(HttpStatusCode.InternalServerError));}}return result;} }然后注冊(cè)至GlobalConfiguration.Configuration.Services中。由于A(yíng)piControllerActionInvoker乃是影響全局的,所以若要對(duì)部分action進(jìn)行包裝處理,應(yīng)該優(yōu)先選擇ActionFilterAttribute。?
DelegatingHandler
前面的攔截都發(fā)生在請(qǐng)求已被路由至對(duì)應(yīng)的action后發(fā)生,有一些情況需要在路由之前就做預(yù)先處理,或是在響應(yīng)流返回過(guò)程中做后續(xù)處理,這時(shí)我們就要用到DelegatingHandler。比如對(duì)請(qǐng)求方的身份驗(yàn)證,當(dāng)驗(yàn)證未通過(guò)時(shí)直接返回錯(cuò)誤信息,否則進(jìn)行后續(xù)調(diào)用。
public class AuthorizeHandler : DelegatingHandler {private static IAuthorizer _authorizer = null;static AuthorizeHandler(){ }protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken){if (request.Method == HttpMethod.Post){var querystring = HttpUtility.ParseQueryString(request.RequestUri.Query);var formdata = request.Content.ReadAsFormDataAsync().Result;if (querystring.AllKeys.Intersect(formdata.AllKeys).Count() > 0){return SendError("請(qǐng)求參數(shù)有重復(fù).", HttpStatusCode.BadRequest);}}//請(qǐng)求方身份驗(yàn)證AuthResult result = _authorizer.AuthRequest(request);if (!result.Flag){return SendError(result.Message, HttpStatusCode.Unauthorized);}request.Properties.Add("shumi_userid", result.UserID);return base.SendAsync(request, cancellationToken);}private Task<HttpResponseMessage> SendError(string error, HttpStatusCode code){var response = new HttpResponseMessage();response.Content = new StringContent(error);response.StatusCode = code;return Task<HttpResponseMessage>.Factory.StartNew(() => response);} }?參考資料:
- ASP.NET Web API Exception Handling
- Implementing message handlers to track your ASP.NET Web API usage
- MVC4 WebAPI(二)——Web API工作方式
- Asp.Net MVC及Web API框架配置會(huì)碰到的幾個(gè)問(wèn)題及解決方案
轉(zhuǎn)載請(qǐng)注明原文出處:http://www.cnblogs.com/newton/p/3238082.html
轉(zhuǎn)載于:https://www.cnblogs.com/smileberry/p/7093326.html
總結(jié)
以上是生活随笔為你收集整理的ASP.NET Web API之消息[拦截]处理(转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 首发2亿像素!moto X30 Pro图
- 下一篇: 【JAVA设计模式】外观模式(Facad