出处:http://www.cnblogs.com/Leo_wl/p/3238719.html

标题相当难取,内容也许和您想的不一样,而且网上已经有很多这方面的资料了,我不过是在实践过程中作下记录。废话少说,直接开始。

Exception


当服务端抛出未处理异常时,most exceptions are translated into an HTTP response with status code 500, Internal Server Error.当然我们也可以抛出一个特殊的异常HttpResponseException,它将被直接写入响应流,而不会被转成500。

public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}

有时要对服务端异常做一封装,以便对客户端隐藏具体细节,或者统一格式,那么可创建一继承自System.Web.Http.Filters.ExceptionFilterAttribute的特性,如下:

public class APIExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
//业务异常
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应用到action或controller,或者GlobalConfiguration.Configuration.Filters.Add(new APIExceptionFilterAttribute());使之应用于所有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());)。当然,在上述代码中,我们也可以在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.

如果要返回给客户端的不仅仅是一串字符串,比如是json对象,那么可以使用HttpError这个类。

以上知识主要来自Exception Handling in ASP.NET Web API

ActionFilterAttribute、ApiControllerActionInvoker


有时要在action执行前后做额外处理,那么ActionFilterAttribute和ApiControllerActionInvoker就派上用场了。比如客户端请求发过来的参数为用户令牌字符串token,我们要在action执行之前先将其转为action参数列表中对应的用户编号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))
{
//参数列表中不存在userid,写入日志
//……
var response = new HttpResponseMessage();
response.Content = new StringContent("用户信息转换异常.");
response.StatusCode = HttpStatusCode.Conflict;
//在这里为了不继续走流程,要throw出来,才会立马返回到客户端
throw new HttpResponseException(response);
}
//userid系统赋值
actionContext.ActionArguments[UserID] = actionContext.Request.Properties["shumi_userid"];
base.OnActionExecuting(actionContext);
} public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
}
}

ActionFilterAttribute如何应用到action,和前面的ExceptionFilterAttribute类似。

ApiControllerActionInvoker以上述Exception为例:

public class ServerAPIControllerActionInvoker : ApiControllerActionInvoker
{
public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
//对actionContext做一些预处理
//……
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;
}
}

然后注册至GlobalConfiguration.Configuration.Services中。由于ApiControllerActionInvoker乃是影响全局的,所以若要对部分action进行包装处理,应该优先选择ActionFilterAttribute。

DelegatingHandler


前面的拦截都发生在请求已被路由至对应的action后发生,有一些情况需要在路由之前就做预先处理,或是在响应流返回过程中做后续处理,这时我们就要用到DelegatingHandler。比如对请求方的身份验证,当验证未通过时直接返回错误信息,否则进行后续调用。

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("请求参数有重复.", HttpStatusCode.BadRequest);
}
}
//请求方身份验证
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);
}
}

参考资料:

转载请注明原文出处:http://www.cnblogs.com/newton/p/3238082.html

 
 

ASP.NET Web API之消息[拦截]处理(转)的更多相关文章

  1. ASP.NET Web API之消息[拦截]处理

    标题相当难取,内容也许和您想的不一样,而且网上已经有很多这方面的资料了,我不过是在实践过程中作下记录.废话少说,直接开始. Exception 当服务端抛出未处理异常时,most exceptions ...

  2. ASP.NET Web API之消息拦截

    要在action执行前后做额外处理,那么ActionFilterAttribute和ApiControllerActionInvoker就派上用场了.比如客户端请求发过来的参数为用户令牌字符串toke ...

  3. ASP.NET WEB API回发到客户端消息体的格式化

    首先基于SOA的消息通信基本都是按照一个统一的协议规范进行交互,那么必须定义消息体.不同的交互结构设计了不同的消息体. 业界统一使用的SOAP是一种规范的XML消息内容.例如在WCF中返回的结果. 随 ...

  4. Asp.Net Web API 2第四课——HttpClient消息处理器

    Asp.Net Web API 导航   Asp.Net Web API第一课:入门http://www.cnblogs.com/aehyok/p/3432158.html Asp.Net Web A ...

  5. 【ASP.NET Web API教程】5.1 HTTP消息处理器

    原文:[ASP.NET Web API教程]5.1 HTTP消息处理器 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内容. 5.1 HTTP ...

  6. 【ASP.NET Web API教程】3.4 HttpClient消息处理器

    原文:[ASP.NET Web API教程]3.4 HttpClient消息处理器 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容. 3.4 ...

  7. ASP.NET Web API WebHost宿主环境中管道、路由

    ASP.NET Web API WebHost宿主环境中管道.路由 前言 上篇中说到ASP.NET Web API框架在SelfHost环境中管道.路由的一个形态,本篇就来说明一下在WebHost环境 ...

  8. 新作《ASP.NET Web API 2框架揭秘》正式出版

    我觉得大部分人都是“眼球动物“,他们关注的往往都是目光所及的东西.对于很多软件从业者来说,他们对看得见(具有UI界面)的应用抱有极大的热忱,但是对背后支撑整个应用的服务却显得较为冷漠.如果我们将整个“ ...

  9. ASP.NET Web API 2框架揭秘

    ASP.NET Web API 2框架揭秘(.NET领域再现力作顶级专家精讲微软全新轻量级通信平台) 蒋金楠 著   ISBN 978-7-121-23536-8 2014年7月出版 定价:108.0 ...

随机推荐

  1. 文档内容类似项处理-Shingling

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jituotianxia2009/article/details/25339807 集合的Jaccar ...

  2. java设计模式--七大原则

    2016-05-14 20:45:38 设计模式到底是五大.六大还是七大,一直傻傻分不清楚,网上总是有说那些原则可以归为一个,我纠结了半天,突然发现自己是舍本逐末了,只要清楚这些原则的设计思想,其他的 ...

  3. java的堆和栈

    初始入门嗯:https://www.cnblogs.com/SaraMoring/p/5687466.html 堆空间:new出来的数组和对象,对象和数组没有引用指向它的时候,等待下一次垃圾回收 栈空 ...

  4. 【转】open-falcon监控windows机器

    open-falcon监控windows机器 时间:2016-05-22 15:34:04   来源:眷恋江南   编辑:涛涛   点击:791   A-A+     最近公司上线了一款新的游戏,用的 ...

  5. word文档批量合并工具

    #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. ; #Warn ; En ...

  6. Java 迭代器 Iterator

    迭代器模式 迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中非常常用的设计模式.这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示. 迭代器模式属于行 ...

  7. 替换res\drawable中的图片

    现象 在android开发中,经常会需要替换res\drawable中的图片,打开res\layout下的文件预览布局页面发现图片已经被替换,但在模拟器或者真实机器上运行时发现该图片并没有被替换,还是 ...

  8. 5月25日-js操作DOM遍历子节点

    一.遍历节点 遍历子节点 children();//获取节点的所有直接子类 遍历同辈节点 next(); prev(); siblings();//所有同辈元素 *find(); 从后代元素中查找匹配 ...

  9. canvas高级动画示例

    canvas高级动画示例 演示地址 https://qzruncode.github.io/example/index.html <!DOCTYPE html> <html lang ...

  10. xml 注释中不允许出现字符串“--“(再也不要来坑爹了,好么,XML)

    转自:https://blog.csdn.net/randomnet/article/details/18708575?utm_source=blogxgwz3 关于xml文件时出现中文注释出错的一个 ...