Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I wrap Web API responses(in .net core) for consistency?

Tags:

I need to return a consistent response with a similar structure returned for all requests. In the previous .NET web api, I was able to achieve this using DelegatingHandler (MessageHandlers). The object that I want to return will be encapsulated in the Result element. So basically the json response will be in this kind of structure:

Example 1:

{     "RequestId":"some-guid-abcd-1234",     "StatusCode":200,     "Result":     {         "Id":42,         "Todo":"Do Hello World"     } } 

Example 2:

{     "RequestId":"some-guid-abcd-1235",     "StatusCode":200,     "Result":     {         [             {                         "Id":42,                 "Todo":"Print Hello World"             },             {                         "Id":43,                 "Todo":"Print Thank you"             }                    ]      } } 

In .NET core, it looks like I need to do this via middleware. I tried but I don't see a nicer way to extract the content like how in the previous web API when you can call HttpResponseMessage.TryGetContentValue to get the content and wrap it in global/common response model.

How can I achieve the same in .NET core?

like image 664
alltej Avatar asked Nov 22 '16 18:11

alltej


1 Answers

I created a middleware to wrap the response for consistency. I also created an extension method to IApplicationBuilder for convenience when registering this middleware. So in Startup.cs, register middleware :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {     //code removed for brevity.     ...     app.UseResponseWrapper();      //code removed for brevity.     ... } 

And here's the middleware code:

using System; using System.IO; using System.Net; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Newtonsoft.Json;  namespace RegistrationWeb.Middleware {     public class ResponseWrapper     {         private readonly RequestDelegate _next;          public ResponseWrapper(RequestDelegate next)         {             _next = next;         }          public async Task Invoke(HttpContext context)         {             var currentBody = context.Response.Body;              using (var memoryStream = new MemoryStream())             {                 //set the current response to the memorystream.                 context.Response.Body = memoryStream;                  await _next(context);                  //reset the body                  context.Response.Body = currentBody;                 memoryStream.Seek(0, SeekOrigin.Begin);                  var readToEnd = new StreamReader(memoryStream).ReadToEnd();                 var objResult = JsonConvert.DeserializeObject(readToEnd);                 var result = CommonApiResponse.Create((HttpStatusCode)context.Response.StatusCode, objResult, null);                 await context.Response.WriteAsync(JsonConvert.SerializeObject(result));             }         }      }      public static class ResponseWrapperExtensions     {         public static IApplicationBuilder UseResponseWrapper(this IApplicationBuilder builder)         {             return builder.UseMiddleware<ResponseWrapper>();         }     }       public class CommonApiResponse     {         public static CommonApiResponse Create(HttpStatusCode statusCode, object result = null, string errorMessage = null)         {             return new CommonApiResponse(statusCode, result, errorMessage);         }          public string Version => "1.2.3";          public int StatusCode { get; set; }         public string RequestId { get; }          public string ErrorMessage { get; set; }          public object Result { get; set; }          protected CommonApiResponse(HttpStatusCode statusCode, object result = null, string errorMessage = null)         {             RequestId = Guid.NewGuid().ToString();             StatusCode = (int)statusCode;             Result = result;             ErrorMessage = errorMessage;         }     } } 
like image 56
alltej Avatar answered Sep 21 '22 04:09

alltej