2012-05-21 4 views
414

HttpClient 개체의 Content-Type 헤더를 내가 요청한 API에 맞게 설정하려고합니다. HttpClient 요청에 대해 Content-Type 헤더를 어떻게 설정합니까?

나는 다음과 같은 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 인 객체와 함께 사용되는지 확인하십시오.

HttpClient 요청에 Content-Type 헤더를 어떻게 설정할 수 있습니까?

답변

513

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

카를로스 솔루션 존스 코멘트를 참조하지 않은 사람들을 위해
+18

다른 방법으로는'Response.Content.Headers'가 대부분 작동합니다. –

+2

@AshishJain ASP.Net 웹 API에 대한'Response.Content.Headers'와 관련된 대부분의 응답은 작동하지 않지만'HttpContext.Current.Response.ContentType'을 사용하여 쉽게 설정할 수 있습니다 if 너 필요해. – jerhewet

+4

@ jerhewet 나는 나를 위해 일한 방식대로 사용했다. var content = new StringContent (data, Encoding.UTF8, "application/json"); –

14

Add 대신 AddWithoutValidation으로 전화하십시오 (this MSDN link 참조).

또는 내가 사용하는 API가 실제로 POST 또는 PUT 요청 (일반 GET 요청이 아님)에만 필요하다고 추측하고 있습니다. 이 경우 HttpClient.PostAsync을 호출하고 HttpContent을 전달하면이 HttpContent 개체의 Headers 속성에이 값을 설정합니다.

+1

AddWithoutValidation이 동일한 오류를 발생합니다. – mynameiscoffey

+0

작동하지 않습니다. –

+0

작동하지 않습니다. '잘못된 헤더 이름을 제공합니다. 요청 헤더가 HttpRequestMessage, HttpResponseMessage가 포함 된 응답 헤더 및 HttpContent 개체가있는 콘텐츠 헤더와 함께 사용되는지 확인하십시오. ' –

91

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); 
     }); 
...

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

그것은 pdf를 다운로드하는 차이를 만들었습니다. 전화에서 HTML을 다운로드하려고했습니다. 확장자를 변환 한 후 파일은 정상적으로 인코딩되었습니다. –

+0

나는 던져야했다.ToString() 끝에,하지만 네,이 WCF 서비스 구현을 위해 일했다. –

33

당신이 작은 라이브러리 의존성을 신경 쓰지 않는 경우, Flurl.Http는 [공시 : 나는 저자 해요]이한다 위버 - 단순. 그것의 PostJsonAsync 메서드는 내용을 serialize하고 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 
+0

콘텐츠가 application/x-www-form-urlencoded 인 경우 보내는 방법은 무엇입니까? –

+0

@Vlado는'PostUrlEncodedAsync'를 사용합니다. http://tmenier.github.io/Flurl/fluent-http/ –

21

시도는 TryAddWithoutValidation

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

작동하지 않습니다. –

+0

작동하지 않으면 '잘못된 헤더 이름이 표시됩니다. 요청 헤더가 HttpRequestMessage, HttpResponseMessage가 포함 된 응답 헤더 및 HttpContent 개체가있는 콘텐츠 헤더와 함께 사용되는지 확인하십시오. ' –

11

닷넷, PUTContent-Type 헤더 만 콘텐츠를 요청 (예 : POST에 지정 될 수 있음을, 즉, 특정 표준을 준수하도록 강요하려고 사용하는 , 등). 따라서 다른 사람이 지적한대로 Content-Type 헤더를 설정하는 가장 좋은 방법은 HttpContent.Headers.ContentType 속성을 사용하는 것입니다.그게

은 (2016년 12월 19일의 예로서 LiquidFiles Api 같은) 특정의 API는 요청에 대한 GETContent-Type 헤더 설정이 필요했다. .Net은 요청 자체에이 헤더를 설정할 수 없으며 심지어 TryAddWithoutValidation을 사용합니다. 또한 길이가 0 인 경우에도 요청에 Content을 지정할 수 없습니다. 이 문제를 해결할 수있는 유일한 방법은 반성에 의지하는 것이 었습니다. 코멘트에서 언급 한 바와 같이

,이 필드는 DLL의 다른 버전에 다른 이름이 있습니다 (경우 다른 일부를 필요에) 코드는

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"); 

편집이다. source code on GitHub에서 필드의 이름은 현재 s_invalidHeaders입니다. 이 예는 @David Thompson의 제안에 따라이를 설명하기 위해 수정되었습니다.

+0

.Net Framework 버전 4.0, System.Net.Http 버전 2.2.29.0과 작동하지 않지만 2.0.0.0과 작동 – prem

+0

이 필드는 이제 s_invalidHeaders이므로 호환성을 보장하려면 다음을 사용하십시오. 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); –

+0

.NET Core 1.1에 대한 대답을 추가했습니다. – Jay

9

(내용이없는 요청에 콘텐츠 형식을 제공하는 개인 필드를 설정하는 방법에 대한 erdomke의 게시물을 읽은 후) .NET 코어에 대한 몇 가지 추가 정보 ... 내 코드를 디버깅 후

, I 반사를 통해 설정할 수있는 비공개 필드가 표시되지 않습니다. 그래서 문제를 재현하려고합니다. 예상대로 내가 가진 동일한 일을 할 경우, 나는, 그러나 내용 "Cannot send a content-body with this verb-type."

으로 집계 예외가,

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; 

그리고 :

나는 닷넷 4.6을 사용하여 다음과 같은 코드를 시도했습니다. NET 코어 (1.1) - 예외가 없습니다. 내 서버 응용 프로그램에서 내 요청에 매우 행복하게 답변했으며 콘텐츠 형식이 선택되었습니다.

나는 그것에 대해 즐겁게 놀랐다. 나는 그것이 누군가를 돕기를 바란다!

+1

고마워요, Jay - 코어를 사용하지 않고, erdomke의 대답을 사용합니다. 모든 합리적인 수단이 시도되었음을 아는 데 감사드립니다 :). –

+0

.NET 코어 실제로 잘 작동합니다, 감사합니다! –

+0

작동하지 않습니다 .net 4 ({ "이 동사 유형의 콘텐츠 본문을 보낼 수 없습니다."}) –

관련 문제