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 (
This is an old question but maybe this will help others.
In AspNetCore 2(not sure if it applies to previous versions) you can add a Custom OutputFormatter
. Below is an implementation using the builtin JsonOutputFormatter
.
Note that this wasn't tested thoroughly and I'm not 100% that changing the context is ok. I looked in the aspnet source code and it didn't seem to matter but I might be wrong.
public class CustomJsonOutputFormatter : JsonOutputFormatter
{
public CustomJsonOutputFormatter(JsonSerializerSettings serializerSettings, ArrayPool charPool)
: base(serializerSettings, charPool)
{ }
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
if (context.HttpContext.Response.StatusCode == (int)HttpStatusCode.OK)
{
var @object = new ApiResponse { Data = context.Object };
var newContext = new OutputFormatterWriteContext(context.HttpContext, context.WriterFactory, typeof(ApiResponse), @object);
newContext.ContentType = context.ContentType;
newContext.ContentTypeIsServerDefined = context.ContentTypeIsServerDefined;
return base.WriteResponseBodyAsync(newContext, selectedEncoding);
}
return base.WriteResponseBodyAsync(context, selectedEncoding);
}
}
and then register it in your Startup class
public void ConfigureServices(IServiceCollection services)
{
var jsonSettings = new JsonSerializerSettings
{
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
options.OutputFormatters.RemoveType();
options.OutputFormatters.Add(new WrappedJsonOutputFormatter(jsonSettings, ArrayPool.Shared));
}