是否可以将默认内容类型设置为“ application / json; v = 2.0”

时间:2019-04-12 04:55:39

标签: c# rest http-headers asp.net-web-api2

是否可以将默认内容类型设置为“ application / json; v = 2.0”。我说默认值是因为我正在使用HttpClient类,并且使用DefaultRequestHeaders来设置代理默认值。

我按照此示例创建了标题https://stackoverflow.com/a/10679340/196526,但是我也使用版本控制,有关版本控制的信息保存在ContenT-Type中

public class BankAccountProxy
{
    public void SetToken()
    {
        Client = new HttpClient();
        Client.BaseAddress = new Uri(System.Configuration.ConfigurationManager.AppSettings["ApiRoute"]);
        Client.DefaultRequestHeaders.Accept.Clear();
        Client.DefaultRequestHeaders.Add("Token", ApiInformations.ApiToken);
        Client.DefaultRequestHeaders
            .Accept
            .Add(new MediaTypeWithQualityHeaderValue($"application/json;v=2.0"));
    }

    public async Task<IEnumerable<BankAccount>> Get()
    {
        HttpResponseMessage response = await Client.GetAsync($"/api/BankAccount/");
        response.EnsureSuccessStatusCode();
        IEnumerable<BankAccount> bankAccount;
        bankAccount = await response.Content.ReadAsAsync<IEnumerable<BankAccount>>();
        return bankAccount;
    }
}

运行此代码时,我得到一个

  

异常消息:值'application / json; v = 2.0'的格式为   无效。

由于v = 2.0可能不是有效的MediaTypeWithQualityHeaderValue。

我要确保始终在Content-Type标头值中发送版本信息。如何初始化?我怎样才能告诉我的代码,我的默认内容类型不是质量头,而是有效头。

有关信息,这是我对Postman的完美查询:

enter image description here

1 个答案:

答案 0 :(得分:4)

TL; DR

使用此代码:

    class Program
    {
        static async Task Main(string[] args)
        {
            try
            {
                var client = new HttpClient { BaseAddress = new Uri("https://contenttypev2.free.beeceptor.com") }; // interceptor
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Add("Token", "SOME_TOKEN"); // simplified

                var response = await client.GetJson2Async("/api/BankAccount/");
                response.EnsureSuccessStatusCode();
                var data = await response.Content.ReadAsStringAsync(); // simplified
                Console.WriteLine(data);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
            finally
            {
                Console.ReadLine();
            }
        }
    }

    class Json2Content : StringContent
    {
        public Json2Content(string content) : this(content, Encoding.Default) { }

        public Json2Content(string content, Encoding encoding) : base(content, encoding)
        {
            this.Headers.Clear();
            this.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            this.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("v", "2.0"));
            if (!encoding.Equals(Encoding.Default)) this.Headers.ContentType.CharSet = encoding.HeaderName;
        }
    }

    static class Json2Extensions
    {
        public static Task<HttpResponseMessage> GetJson2Async(this HttpClient client, string requestUri, string content = "", Encoding encoding = default)
        {
            var request = new HttpRequestMessage(HttpMethod.Get, requestUri) { Content = new Json2Content(content, encoding ?? Encoding.Default) };
            return client.SendAsync(request);
        }
    }

这是结果:

enter image description here

说明

carlosfigueira所述:

内容类型是内容的标头,而不是请求的标头

因此,像在此处一样设置Accept标头:

Client.DefaultRequestHeaders
  .Accept
  .Add(new MediaTypeWithQualityHeaderValue($"application/json;v=2.0"));

不会帮助您实现目标。

要简化JSON v2内容类型的使用,可以使用上面的包装器类以及提供的扩展方法。

注意

您确定要设置Content-Type标头吗?在GET请求中包含内容很少见。 如果您想向服务器发送您希望 接收 的JSON v2响应的信号,则应在Accept标头中执行此操作。甚至您在问题注释中引用的API versioning document都表明可以在Accept标头 Content-Type标头中设置版本号。如果有内容,您仍然可以使用'Accept'标头设置版本,您可以将其作为默认设置,如下所示:

var client = new HttpClient { BaseAddress = new Uri("https://contenttypev2.free.beeceptor.com") }; // interceptor
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add("Token", "SOME_TOKEN"); // simplified
client.DefaultRequestHeaders.Accept.Clear();
var json2MediaType = new MediaTypeWithQualityHeaderValue("application/json");
json2MediaType.Parameters.Clear();
json2MediaType.Parameters.Add(new NameValueHeaderValue("v", "2.0"));
client.DefaultRequestHeaders.Accept.Add(json2MediaType);

var response = await client.GetAsync("/api/BankAccount/");
...

导致:

enter image description here