Cabeçalho personalizado para solicitação HttpClient

140

Como adiciono um cabeçalho personalizado a uma HttpClientsolicitação? Estou usando o PostAsJsonAsyncmétodo para postar o JSON. O cabeçalho personalizado que eu precisaria ser adicionado é

"X-Version: 1"

Isto é o que eu fiz até agora:

using (var client = new HttpClient()) {
    client.BaseAddress = new Uri("https://api.clickatell.com/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "xxxxxxxxxxxxxxxxxxxx");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    var response = client.PostAsJsonAsync("rest/message", svm).Result;
}
Libin Joseph
fonte
3
Possível duplicata da adição de cabeçalhos Http ao HttpClient
Liam
@Liam: Minha pergunta era como adicionar cabeçalhos personalizados. Onde como a outra questão era como adicionar cabeçalhos
Libin Joseph
2
Acho que descobrimos que não devemos descartar o HttpClient. aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
Don Rolando

Respostas:

57
var request = new HttpRequestMessage {
    RequestUri = new Uri("[your request url string]"),
    Method = HttpMethod.Post,
    Headers = {
        { "X-Version", "1" } // HERE IS HOW TO ADD HEADERS,
        { HttpRequestHeader.Authorization.ToString(), "[your authorization token]" },
        { HttpRequestHeader.ContentType.ToString(), "multipart/mixed" },//use this content type if you want to send more than one content type
    },
    Content = new MultipartContent { // Just example of request sending multipart request
        new ObjectContent<[YOUR JSON OBJECT TYPE]>(
            new [YOUR JSON OBJECT TYPE INSTANCE](...){...}, 
            new JsonMediaTypeFormatter(), 
            "application/json"), // this will add 'Content-Type' header for the first part of request
        new ByteArrayContent([BINARY DATA]) {
            Headers = { // this will add headers for the second part of request
                { "Content-Type", "application/Executable" },
                { "Content-Disposition", "form-data; filename=\"test.pdf\"" },
            },
        },
    },
};
Anubis
fonte
38
resposta é extremamente confusa ... por que você está trazendo código para documentos, blank.pdf, etc? instanciando classes de bytearray para passar cabeçalhos personalizados dentro do parâmetro Content?
heug
2
@ heug Bem. Se você está procurando um cabeçalho, pode vê-lo. O conteúdo está presente aqui para concluir a imagem, porque você provavelmente deseja adicionar algum conteúdo à sua solicitação. E, para não ser entediante, o conteúdo é complicado e contém dados JSON e binários.
Anubis
2
parece mais simples fazê-lo assim: crie StringContent usando o seu JSON de conteúdo, crie uma mensagem HTTP com seu método e URI e adicione cabeçalhos como message.Headers.Add ("x": "y") .... depois passe-os para uma resposta var como "var response = waiting httpClient.SendAsync (message);"
heug
@ heug Vou lembrar disso para o furute. Obrigado!
Anubis
3
Qual linha na resposta aceita acima realmente implementa o cabeçalho solicitado pelo OP, versão X? Por que isso é considerado a resposta aceita?
Ron
215

Eu encontrei a resposta para minha pergunta.

client.DefaultRequestHeaders.Add("X-Version","1");

Isso deve adicionar um cabeçalho personalizado à sua solicitação

Libin Joseph
fonte
50
Não, não tem. Essa resposta deve ser vista com cautela, pois os cabeçalhos de solicitação padrão são enviados com cada solicitação. Você deve criar sua solicitação como o @Anubis sugerido. DefaultsRequestHeaders deve ser preenchido quando você cria o HttpClient.
Ruhrpottpatriot
6
Isso funciona apenas porque você está instanciando um novo HttpClient para cada solicitação. Não é assim que esta classe deve ser usada: deve ser um campo estático, reutilizado para todas as solicitações, pelo menos para o mesmo ponto de extremidade. Veja a documentação e inúmeras postagens do blog por aí. Então, como é óbvio, como aponta o @Ruhrpottpatriot, a alteração dos cabeçalhos padrão afetará todas as solicitações.
Kamilk
@Ruhrpottpatriot O que há de errado em enviar o cabeçalho para cada solicitação?
David Klempfner 29/03/19
1
@ajbeaven Não, não é isso que diz. O exemplo na parte superior da página mostra o método Main do aplicativo, portanto, mesmo que o HttpClient seja descartado, a mesma instância é usada durante toda a vida útil do aplicativo, e isso é correto em relação ao que a documentação diz um pouco um pouco mais abaixo: 'O HttpClient deve ser instanciado uma vez e reutilizado ao longo da vida de um aplicativo' . A seguir a este parágrafo, há um exemplo que recomenda atribuir um HttpClient a um campo estático.
Kamilk
1
@ Kamilk, você está absolutamente certo - esse exemplo me colocou errado. Obrigado por me colocar direito :)
ajbeaven
79

Aqui está uma resposta baseada nisso, apresentada por Anubis (que é uma abordagem melhor, pois não modifica os cabeçalhos de todas as solicitações), mas que é mais equivalente ao código da pergunta original:

using Newtonsoft.Json;
...

    var client = new HttpClient();
    var httpRequestMessage = new HttpRequestMessage
        {
            Method = HttpMethod.Post,
            RequestUri = new Uri("https://api.clickatell.com/rest/message"),
            Headers = { 
                { HttpRequestHeader.Authorization.ToString(), "Bearer xxxxxxxxxxxxxxxxxxxx" },
                { HttpRequestHeader.Accept.ToString(), "application/json" },
                { "X-Version", "1" }
            },
            Content = new StringContent(JsonConvert.SerializeObject(svm))
        };

    var response = client.SendAsync(httpRequestMessage).Result;
Chris Peacock
fonte
@RossPresser definitivamente não. Tipo de conteúdo é um cabeçalho de conteúdo.
Panagiotis Kanavos
1
Concordou que esta é a resposta. Ele demonstra como adicionar o cabeçalho solicitado pelo OP. Respondeu minha pergunta também.
Ron
1
Para sua informação, acho que HttpRequestHeader.Accessdeveria HttpRequestHeader.Accept.
Massa Dot Net
o que é svm por sinal?
aswzen
@aswzen É da pergunta do OP - algo que eu acho. O objeto que está sendo serializado.
Chris Peacock
2

Há uma Headerspropriedade na HttpRequestMessageclasse. Você pode adicionar cabeçalhos personalizados lá, que serão enviados com cada solicitação HTTP. A DefaultRequestHeadersna HttpClientclasse, por outro lado, define cabeçalhos para serem enviados com cada solicitação enviada usando esse objeto cliente, daí o nome padrão cabeçalhos de solicitação.

Espero que isso torne as coisas mais claras, pelo menos para alguém que vê esta resposta no futuro.

Bob o construtor
fonte
Não, isso não torna mais claro. Nos dois casos, você está dizendo que está enviando cabeçalhos a cada solicitação. Então, qual é a diferença?
joedotnot
3
Headersé uma propriedade de um HttpRequestMessageobjeto individual . Assim, você pode criar mensagens diferentes com cabeçalhos diferentes. DefaultRequestHeadersé uma propriedade do HttpClientobjeto; se várias mensagens forem enviadas por um determinado HttpClient, todas essas mensagens terão o mesmo valor DefaultRequestHeadersadicionado aos cabeçalhos individuais da mensagem.
Ross Presser