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.