I want to be able to control how json is formatted when I return a content result from a Azure Function (V2). The following is a simplified version of what I am doing:
[FunctionName("CreateThing")]
public static async Task<IActionResult> CreateThingAsync([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "thing")]HttpRequest req, ILogger log)
{
try{
var result = await GetResultAsync(req);
return new CreatedResult($"thing/{result.id}", result);
}
catch(ErrorException) {
return new BadRequestObjectResult(e.Error);
}
}
Is there a way to control how the results are formatted when they are returned, without using attributes on my models? I want to be able to use JsonSerializerSettings but I cant find a way of being able to configure this for the results that are returned as per the example above.
Ran into the same problem myself today.
As Jerry commented, JsonResult
can get you most of the way there; it supports a StatusCode
property:
return new JsonResult(new WorkQueuedResponseMessage
{
...
}, Constants.CommunicationJsonSerializerSettings)
{
StatusCode = StatusCodes.Status202Accepted,
};
For custom headers, my solution is a bit more hacky. I define my own IActionResult
that just sticks headers onto another IActionResult
:
private sealed class HeaderActionResult : IActionResult
{
private readonly IActionResult _result;
public HeaderActionResult(IActionResult result)
{
_result = result;
HeaderDictionary = new HeaderDictionary();
Headers = new ResponseHeaders(HeaderDictionary);
}
public IHeaderDictionary HeaderDictionary { get; }
public ResponseHeaders Headers { get; }
public async Task ExecuteResultAsync(ActionContext context)
{
foreach (var header in HeaderDictionary)
context.HttpContext.Response.Headers.Append(header.Key, header.Value);
await _result.ExecuteResultAsync(context);
}
}
I can then define helper methods if desired:
public static IActionResult EnableCacheHeaders(this IActionResult response, TimeSpan time)
{
return new HeaderActionResult(response)
{
Headers =
{
CacheControl = new CacheControlHeaderValue
{
Public = true,
MaxAge = time,
},
Expires = DateTimeOffset.UtcNow + time,
},
};
}
and use them as such:
return new JsonResult(new WorkAlreadyCompletedResponseMessage
{
...
}, Constants.CommunicationJsonSerializerSettings).EnableCacheHeaders(TimeSpan.FromDays(1));
This works as a way to return IActionResult
with custom JSON serialization, status codes, and headers, while using as many ASP.NET Core types as possible. Hopefully in the future we will get a better integration / injection story.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With