Message interceptor is a class that receives HTTP request and returns the HTTP response, Message handler inherits from the abstract class HttpMessageHandler, message filters before you learn that you should understand the flow of execution under webapi.
The above is the flow of execution webapi, first from the beginning of the implementation of response after an order by the network back to the Request, which after messageHandler, because it is the place webapi architecture can customize the handler to us, and this is almost the past webform. It is based on the http request.
Likely you will say it and filter Aop mode almost ah, but no matter how powerful than anyone else after you read this article, of course, it's useful both are different.
That message interceptor what use is it, I think you should listen to the name you know how it is, it is possible to request a modification request an intermediate layer information in a client where we can be made again; add response headers, reaching the controller before, a parameter validation!
Custom MessageHandler need to inherit System.Net.Http.DelegatingHander
and overloaded method SendAsync
1
2
3
4
5
6
7
8
9
10
11
|
public
class
MessageHandler1 : DelegatingHandler
{
protected
async
override
Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
Debug.WriteLine(
"hello"
);
var
response = await
base
.SendAsync(request, cancellationToken);
Debug.WriteLine(
"bye"
);
return
response;
}
}
|
This is the basic process flow, of course, since you need to add during configuration.
1
2
3
4
5
6
7
8
|
public
static
class
WebApiConfig
{
public
static
void
Register(HttpConfiguration config)
{
config.MessageHandlers.Add(
new
MessageHandler1());
config.MessageHandlers.Add(
new
MessageHandler2());
}
}
|
在消息拦截器中常见的是要判断用户信息,因为像ActionFilterAttribute、ApiControllerActionInvoker、ExceptionFilterAttribute 这些都是在action之前的,那我们就要在之前进行判断。
在HttpRequestMessage中包含了以下属性,这些你都是可以改的。
如何操作header?
1
2
3
4
5
6
7
|
protected
async
override
Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = await
base
.SendAsync(request, cancellationToken);
response.Headers.Add(
"X-Custom-Header"
,
"This is my custom header."
);
return
response;
}
|
首先调用sendAsync将请求传递给inner handler,让它返回响应信息,但是它在创建异步的时候,响应消息是不可用的。
只能全局去配置吗?
1
2
3
4
5
6
7
|
//路由中指定Message Handler
config.Routes.MapHttpRoute(
name:
"Route2"
,
routeTemplate:
"api2/{controller}/{id}"
,
defaults:
new
{ id = RouteParameter.Optional },
handler:
new
MessageHandler2()
// per-route message handler
);
|
这时MessageHandler2替换默认的HttpControllerDispatcher。这个栗子中MessageHandler2创建响应,匹配“Route2”的请求永远不会转到控制器。这使我们可以使用自己的自定义响应替换整个Web API控制器机制。
不知道你有没有想过,如果你的webapi不支持一些特殊的请求,你该怎么办呢,这个时候呵呵,你应该知道了吧!
在这个实例中我们定义了一个集合,在post请求中,一定不是get,那么就有可能是put 或者delete等待的请求头,那么我们可以获取进行修改。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
class
MethodOverrideHandler : DelegatingHandler
{
readonly
string
[] _methods = {
"DELETE"
,
"HEAD"
,
"PUT"
};
const
string
_header =
"X-HTTP-Method-Override"
;
protected
override
Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
if
(request.Method == HttpMethod.Post && request.Headers.Contains(_header))
{
var
method = request.Headers.GetValues(_header).FirstOrDefault();
if
(_methods.Contains(method, StringComparer.InvariantCultureIgnoreCase))
{
request.Method =
new
HttpMethod(method);
}
}
return
base
.SendAsync(request, cancellationToken);
}
}
|
那我们可以获取请求头,如何进行添加呢??
1
2
3
4
5
6
7
8
9
10
|
public
class
CustomHeaderHandler : DelegatingHandler
{
async
protected
override
Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = await
base
.SendAsync(request, cancellationToken);
response.Headers.Add(
"X-Custom-Header"
,
"This is my custom-header."
);
return
response;
}
}
|
在以上代码中我们通过base.SendAsync调用内部消息处理器返回相应结果,base.SendAsync之前是不可响应获取消息的。
这个示例使用了await关键字,以便在SendAsync完成之后异步地执行任务。
1
2
3
4
5
6
7
8
9
10
11
12
|
protected
override
Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
return
base
.SendAsync(request, cancellationToken).ContinueWith(
(task) =>
{
HttpResponseMessage response = task.Result;
response.Headers.Add(
"X-Custom-Header"
,
"This is my custom header."
);
return
response;
}
);
}
|