ASP.Net Core为JSON内容设置内容类型和位置标头

时间:2017-12-21 20:14:32

标签: rest asp.net-core

我有一个API资源,您可以在其中创建新资源。看起来像这样: -

    [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;
    }

这样可以正常工作,因为它满足我的要求,即返回201状态,并具有Content-Type标头的供应商特定MIME类型。但是,我想返回一个Location标题,指向新创建的资源的位置。我不清楚如何将Location标头添加到响应中。我读过关于CreatedResult看起来几乎完全合适的内容。但是,当我使用它时,我认为无法设置Content-Type

所以我的问题是如何使用201状态代码返回带有Location标头和自定义Content-Type的JSON?

2 个答案:

答案 0 :(得分:1)

您可以手动设置标题。直接在控制器或自定义IActionResult类中。

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

答案 1 :(得分:1)

您可以创建自己的outputformatter实现,因为您想要返回Json,而不是二进制数据,您可以从TextOutputFormatter派生(使用 namespace Microsoft.AspNetCore.Mvc.Formatters)。

在该类的构造函数中,您可以设置要返回的内容类型: SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(ContentTypes.VENDOR_MIME_TYPE));

WriteResponseBodyAsync接受上下文参数,您可以使用此参数访问HttpContext,以便您可以将Location标头设置为响应,还可以设置HttpStatusCode Created(201)。

最后,通过将格式化程序添加到MVC选项中,在启动类的ConfigureServices方法中注册格式化程序:

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

如果您需要更进一步,Microsoft文档在此主题上非常出色:https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-formatters