Agregar encabezados HttpClient genera una FormatException con algunos valores


Esto ocurrió en el contexto de la codificación contra Google Cloud Messaging, pero se aplica en otros lugares.

Considere lo siguiente:

var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("key=XXX");

Y

var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", "key=XXX");

Ambos generan una excepción de formato:

Sistema.FormatException: El formato de la clave de valor = XXX ' no es válido.

La solución es eliminar el signo igual.

  1. Profundizar en reflector muestra que hay montones de validación y análisis de código que se ejecutan al agregar a a nuevo valor de encabezado. ¿Por qué es necesario todo esto? ¿No debería este cliente quitarse de en medio?

  2. ¿Cómo escapar del signo igual para que la adición de este valor tenga éxito?

Author: Andrew Shepherd, 2012-11-02

5 answers

No estoy seguro de si sigue siendo relevante, pero recientemente me encontré con este mismo problema y pude resolverlo llamando a un método diferente para agregar la información del encabezado:

var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "key=XXX");
 105
Author: Antonio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-06 08:12:02

A su pregunta "por qué es necesario todo esto (análisis y validación)", la respuesta es: está definido en el estándar HTTP.

En HTTP/1.1 y RFC2617, el valor de un encabezado de autenticación (como WWW-Authenticate y Authorization) tiene dos partes: una parte de esquema y una parte de parámetro.

Para la autenticación básica HTTP, el esquema es "Básico", y el parámetro puede ser algo así como "QWxhZGRpbjpvcGVuIHNlc2FtZQ==" , por lo que la cabecera entera se convierte en:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Es por eso que su "clave=XXX" no pasa la validación, porque carece de una parte de scheme.

 14
Author: Terry Chang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-11 17:48:36

Sorteé esta excepción (mi FormatException causada por comas en el valor) configurando el encabezado Authorization de la siguiente manera:

var authenticationHeaderValue = new AuthenticationHeaderValue("some scheme", "some value");
client.DefaultRequestHeaders.Authorization = authenticationHeaderValue;
 3
Author: CRice,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-23 05:39:52

He estado pasando por algunas preguntas esta mañana mientras se trata de una API externa que no sigue la especificación HTTP al pie de la letra.

Como parte de mi publicación, quieren los Content-Type y Content-Disposition, que no se pueden agregar al objeto HttpClient. Para agregar esas cabeceras, necesita crear un HttpRequestMessage. Allí, necesita agregar las cabeceras a la propiedad Content.

private HttpRequestMessage GetPostMessage(string uri, string contentType,
                                          string fileName, Stream content)
{    
    var request = new HttpRequestMessage
    {
        Content = new StreamContent(content),
        RequestUri = new Uri(uri),
        Method = HttpMethod.Post
    };

    // contentType = "video/mp4"
    request.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);

    //Need TryAddWithoutValidation because of the equals sign in the value.
    request.Content
           .Headers
           .TryAddWithoutValidation("Content-Disposition",
                                    $"attachment; filename=\"{Path.GetFileName(fileName)}\"");

    // If there is no equals sign in your content disposition, this will work:
    // request.Content.Headers.ContentDisposition = 
    //    new ContentDispositionHeaderValue($"attachment; \"{Path.GetFileName(fileName)}\"");

    return request;
}
 0
Author: krillgar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-11 12:05:29

En mi caso estoy generando valores de cadena ETags a partir de un campo SQL byte [] RowVersion. Así que necesito agregar wrap el generado. es decir, AAAAAAAAF5s = cadena dentro de " de la siguiente manera...

        var eTag = department.RowVersion.ToETagString();

        httpClient.DefaultRequestHeaders.Add(Microsoft.Net.Http.Headers.HeaderNames.IfMatch, $"\"{eTag}\"")


    public class DepartmentForHandleDto
    {
        public string Name { get; set; }
        public string GroupName { get; set; }
        public byte[] RowVersion { get; set; }
    }

    public static class ByteArrayExtensions
    {
        public static string ToETagString(this byte[] byteArray)
        {
            return Convert.ToBase64String(byteArray != null && byteArray.Length > 0 ? byteArray : new byte[8]);                    
        }
    }
 0
Author: alhpe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-17 13:14:26