asp.net – Owin Middleware vs ExceptionHandler vs HttpMessageHandler(DelegatingHandler)

前端之家收集整理的这篇文章主要介绍了asp.net – Owin Middleware vs ExceptionHandler vs HttpMessageHandler(DelegatingHandler)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
请任何人给我一些想法,以下三个模块在asp.net Web API 2.1中一起工作

> Owin中间件
> HttpMessageHandler(或DelegatingHandler)
> ExceptionHandler

我想要做的是开发和提供一个不变格式的json数据的web api,意味着如果实际的数据是

  1. {"Id":1,"UserName":"abc","Email":"abc@xyz.com"}

然后我喜欢提供json

  1. {__d:{"Id":1,"Email":"abc@xyz.com"},code:200,somekey: "somevalue"}

为此,我尝试使用自定义ActionFilterAttribute,但我觉得(仍然不能确认),如果代码遇到异常,这样做不能提供类似的格式数据

请建议我最好的方向.

这是我的简短的自定义属性代码片段.还建议我是自定义属性是好的目的

  1. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,Inherited = true,AllowMultiple = false)]
  2. public class ResponseNormalizationAttribute : ActionFilterAttribute
  3. {
  4. public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
  5. {
  6. base.OnActionExecuted(actionExecutedContext);
  7. var response = actionExecutedContext.Response;
  8. object contentValue;
  9. if (response.TryGetContentValue(out contentValue))
  10. {
  11. var nval = new { data=contentValue,status = 200 };
  12.  
  13.  
  14. var newResponse = new HttpResponseMessage { Content = new ObjectContent(nval.GetType(),nval,new JsonMediaTypeFormatter()) };
  15. newResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  16. actionContext.Response = newResponse;
  17. }
  18. }
  19. }

解决方法

如果您不使用Owin中间件,则可以全局包装所有响应,以便使用委托处理程序返回常量格式的json数据.

编写一个继承自DelegatingHandler的自定义处理程序:

  1. public class ApiResponseHandler : DelegatingHandler
  2. {
  3. protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,CancellationToken cancellationToken)
  4. {
  5. var response = await base.SendAsync(request,cancellationToken);
  6.  
  7. return BuildResponse(request,response);
  8. }
  9.  
  10. private static HttpResponseMessage BuildResponse(HttpRequestMessage request,HttpResponseMessage response)
  11. {
  12. object content;
  13. string errorMessage = null;
  14.  
  15. if (response.TryGetContentValue(out content) && !response.IsSuccessStatusCode)
  16. {
  17. HttpError error = content as HttpError;
  18.  
  19. if (error != null)
  20. {
  21. content = null;
  22. errorMessage = error.Message;
  23. }
  24. }
  25.  
  26. var newResponse = request.CreateResponse(response.StatusCode,new ApiResponse((int)response.StatusCode,content,errorMessage));
  27.  
  28. foreach (var header in response.Headers)
  29. {
  30. newResponse.Headers.Add(header.Key,header.Value);
  31. }
  32.  
  33. return newResponse;
  34. }
  35. }
  36.  
  37. //ApiResponse is your constant json response
  38. public class ApiResponse
  39. {
  40.  
  41. public ApiResponse(int statusCode,object content,string errorMsg)
  42. {
  43. Code = statusCode;
  44. Content = content;
  45. Error = errorMsg;
  46. Id = Guid.NewGuid().ToString();
  47. }
  48.  
  49. public string Error { get; set; }
  50.  
  51. //your actual data is mapped to the Content property
  52. public object Content { get; set; }
  53. public int Code { get; private set; }
  54. public string Id { get; set; }
  55. }

在WebApiConfig.cs中注册处理程序:

  1. public static void Register(HttpConfiguration config)
  2. {
  3. // Web API routes
  4. config.MapHttpAttributeRoutes();
  5. ...
  6.  
  7. config.MessageHandlers.Add(new ApiResponseHandler());
  8.  
  9. config.Routes.MapHttpRoute(
  10. name: "DefaultApi",routeTemplate: "{controller}/{id}",defaults: new { id = RouteParameter.Optional }
  11. );
  12.  
  13. ...
  14. }

我在SO中发布了一个类似的答案,但这是在.NET Core中,并被实现为一个OWIN中间件(因为DelegatingHandler在.NET Core中). How can I wrap Web API responses(in .net core) for consistency?

猜你在找的asp.Net相关文章