如何为属性路由创建响应包装器?

时间:2017-06-21 13:31:37

标签: c# asp.net-web-api asp.net-web-api2 attributerouting

使用基于约定的路由时,我可以使用DelegatingHandler通过覆盖SendAsync方法来创建响应包装器。

        DelegatingHandler[] handler = new DelegatingHandler[] {
            new ResponseWrapper()
        };
        var routeHandler = HttpClientFactory.CreatePipeline(new HttpControllerDispatcher(config), handler);

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}",
            defaults: null,
            constraints: null,
            handler: routeHandler
        );

但是,此方法不适用于依赖属性路由的方法。在我的情况下,基于约定的路由不适用于所有场景,并且routeHandler不适用于基于属性的路由。

如何将响应包装应用于所有基于属性的路由响应?

1 个答案:

答案 0 :(得分:0)

我能够添加适用于所有请求的全局消息处理程序。

 config.MessageHandlers.Add(new ResponseWrapper());

由于我使用swagger,我还必须忽略swagger请求URI。这是ResponseWrapper类的代码,它可以帮助某人。我没有机会回过头来,所以肯定会有一些改进......

public class ResponseWrapper : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var response = await base.SendAsync(request, cancellationToken);

            if (request.RequestUri.ToString().Contains("swagger"))
            {
                return response;
            }

            return BuildApiResponse(request, response);
        }

        private static HttpResponseMessage BuildApiResponse(HttpRequestMessage request, HttpResponseMessage response)
        {
            object content = null;
            string errorMessage = null;
            response.TryGetContentValue(out content);

            if (!response.IsSuccessStatusCode)
            {
                content = null;
                var error = new HttpError(response.Content.ReadAsStringAsync().Result);              
                var data = (JObject)JsonConvert.DeserializeObject(error.Message);
                errorMessage = data["message"].Value<string>();

                if (!string.IsNullOrEmpty(error.ExceptionMessage) && string.IsNullOrEmpty(errorMessage))
                {
                    errorMessage = error.ExceptionMessage;
                }
            }

            var newResponse = request.CreateResponse(response.StatusCode, new ApiResponse(response.StatusCode, content, errorMessage));

            foreach (var header in response.Headers)
            {
                newResponse.Headers.Add(header.Key, header.Value);
            }

            return newResponse;
        }
    }