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 (
I can see at least two options to accomplish this.
Firstly, if you want to add this wrapper to all api in the project, you can do this by implementing middleware in the startup.cs part of your project. This is done by adding an app.Use just before the app.UseMvc in the "Configure" function in a similar way as follows:
app.Use(async (http, next) =>
{
//remember previous body
var currentBody = http.Response.Body;
using (var memoryStream = new MemoryStream())
{
//set the current response to the memorystream.
http.Response.Body = memoryStream;
await next();
string requestId = Guid.NewGuid().ToString();
//reset the body as it gets replace due to https://github.com/aspnet/KestrelHttpServer/issues/940
http.Response.Body = currentBody;
memoryStream.Seek(0, SeekOrigin.Begin);
//build our content wrappter.
var content = new StringBuilder();
content.AppendLine("{");
content.AppendLine(" \"RequestId\":\"" + requestId + "\",");
content.AppendLine(" \"StatusCode\":" + http.Response.StatusCode + ",");
content.AppendLine(" \"Result\":");
//add the original content.
content.AppendLine(new StreamReader(memoryStream).ReadToEnd());
content.AppendLine("}");
await http.Response.WriteAsync(content.ToString());
}
});
The other option you have is to intercept the call in a controller. This can be done by overriding the OnActionExecuted function in the controller. Something similar to the following:
public override void OnActionExecuted(ActionExecutedContext context)
{
//
// add code to update the context.Result as needed.
//
base.OnActionExecuted(context);
}