Uniform, consistent error responses from ASP.Net Web API 2

后端 未结 2 1664
醉话见心
醉话见心 2020-12-30 03:36

I\'m developing a Web API 2 application and I\'m currently trying to format error resposnes in a uniform way (so that the consumer will also know what data object/structure

相关标签:
2条回答
  • 2020-12-30 04:03

    You can override the DelegatingHandler abstract class and intercept the response to the client. This will give you the ability to return what you want.

    Here's some info on it. http://msdn.microsoft.com/en-us/library/system.net.http.delegatinghandler(v=vs.118).aspx

    Here's a poster of the Web Api pipeline that shows what can be overriden. http://www.asp.net/posters/web-api/asp.net-web-api-poster.pdf

    Create a Handler class like this to override the response

    public class MessageHandler1 : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, CancellationToken cancellationToken)
        {
            Debug.WriteLine("Process request");
            // Call the inner handler.
            var response = base.SendAsync(request, cancellationToken);
    
            Debug.WriteLine("Process response");
            if (response.Result.StatusCode == HttpStatusCode.NotFound)
            {
                //Create new HttpResponseMessage message
            }
            ;
            return response;
        }
    }
    

    In your WebApiConfig.cs class add the handler.

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

    UPDATE As Kiran mentions in the comments you can use the OwinMiddleware to intercept the response going back to the client. This would work for MVC and Web Api running on any host.

    Here's an example of how to get the response and change it as it goes to the client.

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.Use(typeof(MyMiddleware)); 
        }
    }
    
    public class MyMiddleware : OwinMiddleware
    {
        public MyMiddleware(OwinMiddleware next) : base(next) { }
    
        public override async Task Invoke(IOwinContext context)
        {
            await Next.Invoke(context);
            if(context.Response.StatusCode== 404)
            {
                context.Response.StatusCode = 403;
                context.Response.ReasonPhrase = "Blah";
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-30 04:12

    I have done in same way as @Dan H mentioned

     public class ApiGatewayHandler : DelegatingHandler
    {
        protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            try
            {
                var response = await base.SendAsync(request, cancellationToken);
                if (response.StatusCode == HttpStatusCode.NotFound)
                {
                    var objectContent = response.Content as ObjectContent;
                    return await Task.FromResult(new ApiResult(HttpStatusCode.NotFound, VmsStatusCodes.RouteNotFound, "", objectContent == null ? null : objectContent.Value).Response());
                }
                return response;
            }
            catch (System.Exception ex)
            {
                return await Task.FromResult(new ApiResult(HttpStatusCode.BadRequest, VmsStatusCodes.UnHandledError, ex.Message, "").Response());
            }
    
        }
    }
    

    Added routing like below and now it hits the try catch for invalid url

      config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional });
            config.Routes.MapHttpRoute(name: "NotFound", routeTemplate: "api/{*paths}", defaults: new { controller = "ApiError", action = "NotFound" });
    
    0 讨论(0)
提交回复
热议问题