视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
.Net WebApi消息之MessageHandler的示例
2020-11-27 22:34:57 责编:小采
文档


消息是一个类,接收 HTTP request并返回 HTTP response,Message handler 继承自抽象类 HttpMessageHandler
可以自定义 MessageHandler,消息的作用如:

  1. 读取或更改请求头 request headers
  2. 添加 response headers
  3. 在到达 controller 之前,进行参数验证


自定义 Message Handlers

自定义 MessageHandler 需要继承 System.Net.Http.DelegatingHander 并且重载SendAsync方法

Task<HttpResponseMessage> SendAsync(
 HttpRequestMessage request, CancellationToken cancellationToken);

这个方法的一般的处理流程是

  1. 处理请求信息
  2. 调用 base.SendAsync 方法,吧请求发送给内部处理
  3. 内部处理完成之后,返回 response message(这个过程是异步的)
  4. 处理 response 之后,返回给调用者
public class MessageHandler1 : DelegatingHandler
{
 protected async override Task<HttpResponseMessage> SendAsync(
 HttpRequestMessage request, CancellationToken cancellationToken)
 {
 Debug.WriteLine("Process request");
 // Call the inner handler.
 var response = await base.SendAsync(request, cancellationToken);
 Debug.WriteLine("Process response");
 return response;
 }
}

消息生效

WebApiConfig中注册相关

public static class WebApiConfig
{
 public static void Register(HttpConfiguration config)
 {
 config.MessageHandlers.Add(new MessageHandler1());
 config.MessageHandlers.Add(new MessageHandler2());

 // Other code not shown...
 }
}

https 请求

要求所有的请求都必须是https的请求,可以自定义一个https的,如果是https请求,就继续处理,否则就返回相关的提示信息

public class RequireHttpsHandler : DelegatingHandler
{
 public RequireHttpsHandler(int httpsPort)
 {
 _httpsPort = httpsPort;
 }

 public RequireHttpsHandler()
 : this(443)
 {
 }

 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
 {
 //判断是否是 https 请求
 if (request.RequestUri.Scheme == Uri.UriSchemeHttps)
 return base.SendAsync(request, cancellationToken);

 var response = CreateResponse(request);
 var tcs = new TaskCompletionSource<HttpResponseMessage>();
 tcs.SetResult(response);
 return tcs.Task;
 }

 private HttpResponseMessage CreateResponse(HttpRequestMessage request)
 {
 HttpResponseMessage response;
 var uri = new UriBuilder(request.RequestUri);
 uri.Scheme = Uri.UriSchemeHttps;
 uri.Port = _httpsPort;
 var body = string.Format("HTTPS is required<br/>The resource can be found at <a href=\"{0}\">{0}</a>.", uri.Uri.AbsoluteUri);
 if (request.Method.Equals(HttpMethod.Get) || request.Method.Equals(HttpMethod.Head))
 {
 response = request.CreateResponse(HttpStatusCode.Found);
 response.Headers.Location = uri.Uri;
 if (request.Method.Equals(HttpMethod.Get))
 response.Content = new StringContent(body, Encoding.UTF8, "text/html");
 }
 else
 {
 response = request.CreateResponse(HttpStatusCode.NotFound);
 response.Content = new StringContent(body, Encoding.UTF8, "text/html");
 }

 return response;
 }
}

Enable CORS

public class SimpleCorsHandler : DelegatingHandler
{
 private const string origin = "Origin";
 private const string accessControlRequestMethod = "Access-Control-Request-Method";
 private const string accessControlRequestHeaders = "Access-Control-Request-Headers";
 private const string accessControlAllowOrigin = "Access-Control-Allow-Origin";
 private const string accessControlAllowMethods = "Access-Control-Allow-Methods";
 private const string accessControlAllowHeaders = "Access-Control-Allow-Headers";

 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
 CancellationToken cancellationToken)
 {
 var isCorsRequest = request.Headers.Contains(origin);
 var isPreflightRequest = request.Method == HttpMethod.Options;

 if (isCorsRequest)
 {
 if (isPreflightRequest)
 {
 return Task.Factory.StartNew(() =>
 {
 var response = new HttpResponseMessage(HttpStatusCode.OK);
 response.Headers.Add(accessControlAllowOrigin,
 request.Headers.GetValues(origin).First());

 var currentAccessControlRequestMethod =
 request.Headers.GetValues(accessControlRequestMethod).
 FirstOrDefault();

 if (currentAccessControlRequestMethod != null)
 {
 response.Headers.Add(accessControlAllowMethods,
 currentAccessControlRequestMethod);
 }

 var requestedHeaders = string.Join(", ", request.Headers.GetValues(accessControlRequestHeaders));

 if (!string.IsNullOrEmpty(requestedHeaders))
 {
 response.Headers.Add(accessControlAllowHeaders,
 requestedHeaders);
 }

 return response;
 }, cancellationToken);
 }
 else
 {
 return base.SendAsync(request, cancellationToken).ContinueWith(t =>
 {
 var resp = t.Result;
 resp.Headers.Add(
 accessControlAllowOrigin,
 request.Headers.GetValues(origin).First());

 return resp;
 });
 }
 }
 else
 {
 return base.SendAsync(request, cancellationToken);
 }
 }
}

下载本文
显示全文
专题