호출하는 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
합니까?
답변
컨텐츠 유형은 요청이 아닌 컨텐츠의 헤더이므로 이것이 실패하는 이유입니다. AddWithoutValidation
Robert 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-Type
는 GET
요청에 대한 헤더를 설정해야합니다 . .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
하고 전달할 때 해당 객체 HttpContent
의 Headers
속성 에서 설정하십시오 HttpContent
.