Kaip nustatyti turinio tipo antraštę HttpClient užklausai?

Bandau nustatyti „ HttpClient objekto Content-Type antraštę, kaip reikalauja API.

Bandžiau nustatyti Content-Type taip:

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

Tai leidžia man pridėti „ Accept antraštę, bet kai bandau pridėti Content-Type , jis išmeta šią išimtį:

Neteisingas antraštės pavadinimas. Užtikrinkite, kad užklausos antraštės būtų naudojamos su HttpRequestMessage , atsakymų antraštėmis su HttpResponseMessage ir turinio antraštėmis su HttpContent objektais.

Kaip nustatyti Content-Type antraštę HttpClient užklausoje?

372
21 мая '12 в 6:29 2012-05-21 06:29 mynameiscoffey yra nustatytas gegužės 21 d ., 12 val., 12:29 2012-05-21 06:29
@ 7 atsakymai

Turinio tipas yra turinio antraštė, o ne prašymas, todėl jis neveikia. AddWithoutValidation , kaip pasiūlė Robert Levy, gali dirbti, tačiau turinio tipą taip pat galite naudoti kurdami paties turinio turinį (atkreipkite dėmesį, kad kodo fragmentas dviejose vietose prideda „taikomąją programą“ / „Priimti ir turinį“ tipo antraštes):

 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); }); 
460
21 мая '12 в 6:54 2012-05-21 06:54 atsakymą pateikė carlosfigueira gegužės 21 d., 12 val., 06:54 2012-05-21 06:54

Tiems, kurie nematė Joneso komentaro dėl carloso sprendimo ...

border=0
 req.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
84
06 июня '13 в 13:15 2013-06-06 13:15 atsakymas įteiktas birželio 6 d. 13 val. 13:15 2013-06-06 13:15

Jei nežinote mažos bibliotekos priklausomybės, Flurl.Http [atskleidimas: aš esu autorius] daro šį paprastą, jo PostJsonAsync metodas suteikia tiek turinio serializavimą, tiek turinio content-type antraštę, ir „ ReceiveJson - atsakymo deserializavimas. Jei reikia accept antraštę, turėsite ją įdiegti patys, bet „Flurl“ taip pat suteikia gana švarų būdą:

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

„Flurl“ naudoja „HttpClient“ ir „Json.NET“ po gaubtu, ir tai yra PCL, todėl ji veiks įvairiose platformose.

 PM> Install-Package Flurl.Http 
30
22 июня '14 в 18:19 2014-06-22 18:19 atsakymas duotas Todd Menierui birželio 22 d. 14 val. 19:19

pabandykite naudoti „TryAddWithoutValidation“

  var client = new HttpClient(); client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json; charset=utf-8"); 
21
20 нояб. atsakymą pateikė „ SharpCoder“ lapkričio 20 d 2015-11-20 01:48 '15 ne 1:48 2015-11-20 01:48

Skambinkite AddWithoutValidation vietoj Add (žr. Šią MSDN nuorodą ).

Taip pat manau, kad jūsų naudojama API reikalauja tik POST arba PUT užklausų (ne įprastų GET užklausų). Tokiu atveju, kai skambinate „ HttpClient.PostAsync ir perduodate „ HttpContent , nustatykite šį „ HttpContent objekto „ Headers nuosavybę.

12
21 мая '12 в 6:32 2012-05-21 06:32 atsakymą pateikė Robert Levy , gegužės 21 d., 12 val. 6:32 2012-05-21 06:32

.Net bando priversti jus paklusti tam tikriems standartams, ty kad Content-Type antraštę galima nurodyti tik tose užklausose, kuriose yra turinys (pvz., POST , PUT ir tt). Todėl, kaip kiti nurodė, pageidaujamas būdas nustatyti Content-Type antraštę yra „ HttpContent.Headers.ContentType ypatybėje.

Tuo pačiu metu kai kurioms API (pvz., „ LiquidFiles Api“ , pradedant nuo 2016-12-19) reikia nustatyti „ Content-Type antraštę „ GET . Be to, negalite nurodyti Content užklausai - net jei jis turi nulinį ilgį. Vienintelis būdas, kaip aš galėčiau tai padaryti, yra mąstymas. Kodas (jei ji vis dar reikalinga) -

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

Redaguoti:

Kaip pažymėta komentaruose, šiame lauke yra skirtingi pavadinimai skirtingose ​​dll versijose. GitHub lauko šaltinio kodas šiuo metu vadinamas s_invalidHeaders . Pavyzdys buvo pakeistas, kad į jį būtų atsižvelgta prielaidoje „@David Thompson“.

11
20 дек. atsakymas duotas 20 d. 2016-12-20 00:32 '16 at 0:32 2016-12-20 00:32

Daugiau informacijos apie .NET Core (perskaičius „erdomke“ pranešimą apie privataus lauko nustatymą, kad pateiktumėte turinio tipą užklausoje, kurioje nėra turinio) ...

Po derinimo mano kodo, nematau, kaip privataus lauko nustatoma per atspindį, todėl aš maniau, kad bandysiu atkurti problemą.

Bandžiau naudoti šį kodą naudodami .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; 

Ir, kaip tikėtasi, gaunu bendrą išimtį su "Cannot send a content-body with this verb-type."

Tačiau, jei darau tą patį su .NET Core (1.1) - , aš negavau išimties. Mano prašymas buvo gana laimingas atsakant į serverio programą, o turinio tipas buvo iškeltas.

Tai maloniai nustebino, ir tikiuosi, kad tai padės kam nors!

7
12 июня '17 в 11:48 2017-06-12 11:48 Atsakymą pateikė Jay birželio 12 d. 17 val. 11:48 2017-06-12 11:48

Kiti klausimai apie žymes arba Užduoti klausimą