[C#] HttpClient 요청에 대해 Content-Type 헤더를 어떻게 설정합니까?

호출하는 API에 필요한 객체 Content-Type헤더 를 설정하려고합니다 HttpClient.

Content-Type아래와 같이 설정을 시도했습니다 .

using (var httpClient = new HttpClient())
{
    httpClient.BaseAddress = new Uri("http://example.com/");
    httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
    httpClient.DefaultRequestHeaders.Add("Content-Type", "application/json");
    // ...
}

Accept헤더 를 추가 할 수는 있지만 추가하려고 Content-Type하면 다음 예외가 발생합니다.

헤더 이름이 잘못되었습니다. 요청 헤더 HttpRequestMessage는와 함께 사용하고 응답 헤더는와 함께 사용 HttpResponseMessage하고 콘텐츠 헤더는 HttpContent객체 와 함께 사용해야
합니다.

요청 에서 Content-Type헤더를 어떻게 설정 HttpClient합니까?



답변

컨텐츠 유형은 요청이 아닌 컨텐츠의 헤더이므로 이것이 실패하는 이유입니다. AddWithoutValidationRobert Levy가 제안한대로 작동 할 수도 있지만 요청 컨텐츠 자체를 작성할 때 컨텐츠 유형을 설정할 수도 있습니다 (코드 스 니펫은 Accept 및 Content-Type 헤더의 두 위치에 “application / json”을 추가 함).

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://example.com/");
client.DefaultRequestHeaders
      .Accept
      .Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "relativeAddress");
request.Content = new StringContent("{\"name\":\"John Doe\",\"age\":33}",
                                    Encoding.UTF8,
                                    "application/json");//CONTENT-TYPE header

client.SendAsync(request)
      .ContinueWith(responseTask =>
      {
          Console.WriteLine("Response: {0}", responseTask.Result);
      });


답변

Johns가 carlos 솔루션에 대해 언급하지 않은 사람들을 위해 …

req.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");


답변

작은 라이브러리 종속성을 신경 쓰지 않으면 Flurl.Http [공개 : 저자입니다]는이를 간단하게 만듭니다. 이 PostJsonAsync방법은 내용을 직렬화하고 content-type헤더를 설정 ReceiveJson하고 응답을 역 직렬화합니다. accept헤더가 필요한 경우 직접 설정해야하지만 Flurl 은이를 수행하는 매우 깨끗한 방법을 제공합니다.

using Flurl.Http;

var result = await "http://example.com/"
    .WithHeader("Accept", "application/json")
    .PostJsonAsync(new { ... })
    .ReceiveJson<TResult>();

Flurl은 HttpClient와 Json.NET을 사용하며 PCL이므로 다양한 플랫폼에서 작동합니다.

PM> Install-Package Flurl.Http


답변

TryAddWithoutValidation을 사용해보십시오

  var client = new HttpClient();
  client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json; charset=utf-8");


답변

닷넷은 즉 것으로, 특정 표준을 준수하도록 강요하려고 Content-Type헤더 만 콘텐츠를 요청 (예 지정할 수 있습니다 POST, PUT등). 따라서 다른 사람들이 지적 Content-Type했듯이 헤더 를 설정하는 바람직한 방법 은 HttpContent.Headers.ContentType속성을 통하는 것 입니다.

그렇게 말하면 특정 API (예 : 2016-12-19 현재 LiquidFiles Api ) Content-TypeGET요청에 대한 헤더를 설정해야합니다 . .Net은 요청 자체에서이 헤더를 설정하는 것을 허용하지 않습니다 TryAddWithoutValidation. 또한 Content길이가 0 인 경우에도 요청에 대해를 지정할 수 없습니다 . 내가이 문제를 해결할 수있는 유일한 방법은 반사에 의지하는 것입니다. 코드 (다른 사람이 필요로하는 경우)는

var field = typeof(System.Net.Http.Headers.HttpRequestHeaders)
    .GetField("invalidHeaders", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static)
  ?? typeof(System.Net.Http.Headers.HttpRequestHeaders)
    .GetField("s_invalidHeaders", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
if (field != null)
{
  var invalidFields = (HashSet<string>)field.GetValue(null);
  invalidFields.Remove("Content-Type");
}
_client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "text/xml");

편집하다:

주석에서 언급했듯이이 필드는 dll 버전마다 이름이 다릅니다. GitHub소스 코드에서 필드의 이름은 현재 s_invalidHeaders입니다. @David Thompson의 제안에 따라이 예를 설명하도록 예제가 수정되었습니다.


답변

.NET Core에 대한 몇 가지 추가 정보 (콘텐츠가없는 요청에서 콘텐츠 유형을 제공하기 위해 개인 필드 설정에 대한 Erdomke의 게시물을 읽은 후) …

내 코드를 디버깅 한 후 리플렉션을 통해 설정할 개인 필드를 볼 수 없으므로 문제를 재현하려고 생각했습니다.

.Net 4.6을 사용하여 다음 코드를 시도했습니다.

HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Get, @"myUrl");
httpRequest.Content = new StringContent(string.Empty, Encoding.UTF8, "application/json");

HttpClient client = new HttpClient();
Task<HttpResponseMessage> response =  client.SendAsync(httpRequest);  //I know I should have used async/await here!
var result = response.Result;

그리고 예상대로 콘텐츠에 대한 총체 예외가 발생합니다. "Cannot send a content-body with this verb-type."

그러나 .NET Core (1.1)와 동일한 작업을 수행하면 예외가 발생하지 않습니다.내 서버 응용 프로그램에서 내 요청에 매우 만족스럽게 응답하고 내용 유형을 선택했습니다.

나는 그것에 대해 유쾌하게 놀랐으며, 누군가에게 도움이되기를 바랍니다!


답변

AddWithoutValidation대신 호출 Add하십시오 ( 이 MSDN 링크 참조 ).

또는 사용중인 API가 POST 또는 PUT 요청 (일반적인 GET 요청이 아닌)에 대해서만 필요하다고 생각합니다. 이 경우을 호출 HttpClient.PostAsync하고 전달할 때 해당 객체 HttpContentHeaders속성 에서 설정하십시오 HttpContent.