When in my REST API should I use an envelope? If I use it in one place, should I always use it?

前端 未结 5 1592
面向向阳花
面向向阳花 2020-12-03 02:33

I\'m working on building a RESTful web service. I have read up on the principles of using HTTP for every mechanism as far as it will take you, and most of the time, like whe

5条回答
  •  难免孤独
    2020-12-03 03:15

    I used to resist the idea of enveloping the response due to the overhead of requireing to encapsulate each WebApi action.

    Then I stumbled upon this article which does it in neat way that doesnt require any extra effort and it just works

    Handler

    public class WrappingHandler : DelegatingHandler
    {
        protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var response = await base.SendAsync(request, cancellationToken);
    
            return BuildApiResponse(request, response);
        }
    
        private static HttpResponseMessage BuildApiResponse(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;
    
    #if DEBUG
                    errorMessage = string.Concat(errorMessage, error.ExceptionMessage, error.StackTrace);
    #endif
                }
            }
    
            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;
        }
    }
    

    Envelope

    Custom wrapper class [DataContract]

    public class ApiResponse
    {
        [DataMember]
        public string Version { get { return "1.2.3"; } }
    
        [DataMember]
        public int StatusCode { get; set; }
    
        [DataMember(EmitDefaultValue = false)]
        public string ErrorMessage { get; set; }
    
        [DataMember(EmitDefaultValue = false)]
        public object Result { get; set; }
    
        public ApiResponse(HttpStatusCode statusCode, object result = null, string errorMessage = null)
        {
            StatusCode = (int)statusCode;
            Result = result;
            ErrorMessage = errorMessage;
        }
    }
    

    Register it!

    in WebApiConfig.cs in App_Start

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

提交回复
热议问题