简体   繁体   English

如何从Web API 2强制使用Content-Type MediaTypeFormatter

[英]How to force the Content-Type from a Web API 2 MediaTypeFormatter

I have an issue with my MediaTypeFormatter. 我的MediaTypeFormatter有问题。 When I make a request with the Accept header set to "application/vnd.siren+json", it correctly sets the response to have Content Type header set to "application/vnd.siren+json". 当我在接受标头设置为“ application / vnd.siren + json”的情况下发出请求时,它正确地将响应设置为将内容类型标头设置为“ application / vnd.siren + json”。

What I am trying to do is even when I do not state explicitly that I want "application/vnd.siren+json", I would like to set the response content type to be "application/vnd.siren+json". 我试图做的是即使我没有明确声明我想要“ application / vnd.siren + json”,我也想将响应内容类型设置为“ application / vnd.siren + json”。

For example, a bog-standard call will have this Accept header set: 例如,沼泽标准呼叫将设置以下“接受”标头:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

When I do a GET using that Accept header, my response type will be application/xml and not application/vnd.siren+json. 当我使用该Accept头执行GET时,我的响应类型将是application / xml而不是application / vnd.siren + json。

WebApiConfig.cs has been configured as: WebApiConfig.cs已配置为:

SirenMediaTypeFormatter sirenMediaTypeFormatter = new SirenMediaTypeFormatter();
sirenMediaTypeFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
sirenMediaTypeFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/vnd.siren+json"));
config.Formatters.Insert(0, sirenMediaTypeFormatter);

I have set up my MediaTypeFormatter as: 我将我的MediaTypeFormatter设置为:

public class SirenMediaTypeFormatter : JsonMediaTypeFormatter 
{
    private static Type _supportedType = typeof(Entity);
    private const string _mediaType = "application/vnd.siren+json";

    public SirenMediaTypeFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue(_mediaType));
    }

    public override bool CanReadType(Type type)
    {
        return type == _supportedType;
    }

    public override bool CanWriteType(Type type)
    {
        bool blnRetval = (typeof(Entity).IsAssignableFrom(type));
        return blnRetval;
    }


    public override Task WriteToStreamAsync(Type type, object value,
   Stream stream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
    {
        return Task.Factory.StartNew(() =>
        {
            if (typeof(Entity).IsAssignableFrom(type))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue(_mediaType);

                var objectToSerialize = BuildSirenDocument(value, stream, content.Headers.ContentType.MediaType);


                var jsonSerializerSettings = new JsonSerializerSettings
                {
                    ContractResolver = new CamelCasePropertyNamesContractResolver()
                };

                string jsonResult = Newtonsoft.Json.JsonConvert.SerializeObject(objectToSerialize, jsonSerializerSettings);

                StreamWriter writer = new StreamWriter(stream);
                writer.Write(jsonResult);
                writer.Flush();

            }
        });
    }

I have tried to update the value of the Context using content.Headers.ContentType = new MediaTypeHeaderValue(_mediaType); 我试图使用content.Headers.ContentType = new MediaTypeHeaderValue(_mediaType);更新Context的值。 however 1). 但是1)。 it does not work and the content type remains set to application/xml and 2). 它不起作用,内容类型仍设置为application / xml和2)。 I worry about playing around with Context in a WriteAsynch method like this. 我担心像这样在WriteAsynch方法中玩弄Context。

How do I go about forcing my Response header type (without setting it explicitly in the controller). 我该如何强制我的Response标头类型(没有在控制器中显式设置)。

It's too late to write the headers by the time WriteToStreamAsync is called as you allude to in your question. 正如您在问题中提到的那样,在调用WriteToStreamAsync写入标头为时已晚。 Instead you need to override SetDefaultContentHeaders . 相反,您需要重写SetDefaultContentHeaders

From the documentation, this: 从文档中,这是:

Sets the default headers for content that will be formatted using this formatter. 设置将使用此格式化程序格式化的内容的默认标题。

To change the Content Type you can pass through your own MediaTypeHeaderValue to the base method: 要更改内容类型,您可以将自己的MediaTypeHeaderValue传递给基本方法:

public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
    base.SetDefaultContentHeaders(type, headers, new MediaTypeHeaderValue(_mediaType));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 REST WEB API:如何使Content-Type标头为可选? - REST WEB API: How to make Content-Type header optional? 设置Web API 2响应的内容类型 - Setting content-type for Web API 2 response 使用带有备用内容类型的c#web api - Using c# web api with alternate content-type 如何使用Content-Type:multipart / form-data通过Web API请求主体参数访问? - How request body parameter access by Web API using Content-Type: multipart/form-data? 在.NET MVC 4(Web API)中,如何拦截控制器请求并更改其内容类型? - In .NET MVC 4 (Web API), how do I intercept a request for a controller and change it's Content-Type? 如何将Content-Type标头添加到.Net GET Web请求? - How to add the Content-Type header to a .Net GET web request? 是否有内容的内容类型标头,就像对Web api的PUT / POST请求中的请求标头一样 - Is it necessary to have content-type headers for content much like request headers in a PUT/POST request to web api 内容类型XML的Web Api返回完整的类-而JSON仅返回ID - Web Api of content-type XML returns complete class - while JSON returns just ID .net 6 web api - 请求正文中的错误“Content-Type”属性 - 返回 400 状态而不是 500 - .net 6 web api - bad "Content-Type" property in request body - return 400 status instead of 500 C# HttpRequestMessage Content-Type 强制为“application/json” - C# HttpRequestMessage Content-Type force as "application/json" only
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM