asp.net - Owin 中间件 vs ExceptionHandler vs HttpMessageHandler (DelegatingHandler)

标签 asp.net json asp.net-web-api

请任何人告诉我以下三个模块如何在 asp.net Web API 2.1 中协同工作

  • 欧文中间件
  • HttpMessageHandler(或 DelegatingHandler)
  • 异常处理程序

  • 我正在尝试做的是开发一个 web api,它将提供一个恒定格式的 json 数据,这意味着如果实际数据是
    {"Id":1,"UserName":"abc","Email":"abc@xyz.com"}
    

    然后我喜欢将 json 传递为
    {__d:{"Id":1,"UserName":"abc","Email":"abc@xyz.com"}, code:200, somekey: "somevalue"}
    

    为此,我尝试使用自定义 Action 过滤器属性 但我觉得(仍然无法确认)如果代码遇到异常,这将无法提供类似格式的数据

    请建议我最好的方向。

    这是我的自定义属性的简短代码片段。还建议我自定义属性是否适合此目的
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
    public class ResponseNormalizationAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
                base.OnActionExecuted(actionExecutedContext);
                var response = actionExecutedContext.Response;
                object contentValue;
                if (response.TryGetContentValue(out contentValue))
                {
                    var nval = new { data=contentValue, status = 200 };
    
    
                    var newResponse = new HttpResponseMessage { Content = new ObjectContent(nval.GetType(), nval, new JsonMediaTypeFormatter()) };
                    newResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                    actionContext.Response = newResponse;
                }
         }
    }
    

    最佳答案

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

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

    public class ApiResponseHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var response = await base.SendAsync(request, cancellationToken);
    
            return BuildResponse(request, response);
        }
    
        private static HttpResponseMessage BuildResponse(HttpRequestMessage request, HttpResponseMessage response)
        {
            object content;
            string errorMessage = null;
    
            if (response.TryGetContentValue(out content) && !response.IsSuccessStatusCode)
            {
                HttpError error = content as HttpError;
    
                if (error != null)
                {
                    content = null;
                    errorMessage = error.Message;
                }
            }
    
            var newResponse = request.CreateResponse(response.StatusCode, new ApiResponse((int)response.StatusCode, content, errorMessage));
    
            foreach (var header in response.Headers)
            {
                newResponse.Headers.Add(header.Key, header.Value);
            }
    
            return newResponse;
        }
    }
    
    //ApiResponse is your constant json response
    public class ApiResponse
    {
    
        public ApiResponse(int statusCode, object content, string errorMsg)
        {
            Code = statusCode;
            Content = content;
            Error = errorMsg;
            Id = Guid.NewGuid().ToString();
        }
    
        public string Error { get; set; }
    
        //your actual data is mapped to the Content property
        public object Content { get; set; }
        public int Code { get; private set; }
        public string Id { get; set; }
    }
    

    WebApiConfig.cs 中注册处理程序:
        public static void Register(HttpConfiguration config)
        {
            // Web API routes
            config.MapHttpAttributeRoutes();
            ...
    
            config.MessageHandlers.Add(new ApiResponseHandler());
    
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
    
            ...
        }
    

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

    关于asp.net - Owin 中间件 vs ExceptionHandler vs HttpMessageHandler (DelegatingHandler),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24156853/

    相关文章:

    c# - 如何创建由 5 个子图组成的图表

    c# - 如何获取数据表各列的绝对值之和

    c# - 同一应用程序中 MVC 的 Cookie 身份验证和 WebAPI 的 OAuth

    javascript - 在 setInterval 时间中使用 JSON 变量

    c# - Entity Framework 数据库首先出现加载相关实体的问题(ASP.NET Web api)

    Asp.net Web API DateTimeOffset 设置与 http header 的偏移量

    c# - 通过 Asp.Net Web Api 发送电子邮件

    html - 模板字段宽度在 asp.net 的 GridView 中没有增加

    asp.net - 如何为 .Net 网站、Windows 服务等创建安装程序?

    ios - 如何使用 URLSession (Swift 4.2) 触发两 (2) 个 HTTP POST 请求?