简体   繁体   中英

ASP.Net Core set Content-Type and Location headers for JSON content

I have an API resource where you can create a new resource. That looks like so:-

    [HttpPost("/content")]
    public JsonResult PostContent([FromBody] ContentCreate content)
    {
        JsonResult result;
        if (ModelState.IsValid) {
            var newContent = _contentService.Create(content);
            result = Json(newContent);
            result.StatusCode = (int)HttpStatusCode.Created;
            result.ContentType = ContentTypes.VENDOR_MIME_TYPE;
        }
        else {
            var error = new ClientError(ModelState){
                Code = ErrorCodes.INVALID_CONTENT,
                Description = "Content is invalid"
            };
            result = Json(error);
            result.StatusCode = (int)HttpStatusCode.BadRequest;
            result.ContentType = ContentTypes.VENDOR_MIME_TYPE_ERROR;
        }

        return result;
    }

This works fine as it satisfies my requirements to return a 201 status, and have a vendor specific MIME type for the Content-Type header. However, I want to return a Location header pointing at the location of the newly created resource. I am not clear on how to add the Location header to the response. I have read about CreatedResult which looks almost the perfect fit. However, I see no way to set the Content-Type when I use that.

So my question is how do I return JSON, with a 201 status code, with a Location header and a custom Content-Type ?

You could set the header manually. Either directly in the controller or in a custom IActionResult class.

HttpContext.Response.Headers["Location"] = "...";

You can create your own implementation of an outputformatter, since you want to return Json, and not binary data, you can derive from TextOutputFormatter (using the namespace Microsoft.AspNetCore.Mvc.Formatters ).

In the constructor of that class you can set the content type you want to return: SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(ContentTypes.VENDOR_MIME_TYPE));

The WriteResponseBodyAsync accepts a context parameter, you can use this parameter to access the HttpContext so you can set the Location header to the response, and also set the HttpStatusCode Created (201).

Finally, register the formatter in the ConfigureServices method, in the startup class, by adding it to the MVC Options:

services.AddMvc(options =>
{   
    options.OutputFormatters.Insert(0, new MyOutputFormatter());
});

If you need to go further from here, the Microsoft docs are really good on this subject: https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-formatters

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM