添加HttpClient标头会生成带有一些值的FormatException

问题描述 投票:58回答:6

这发生在针对Google Cloud Messaging的编码环境中,但适用于其他地方。

考虑以下:

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

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

这两个都生成FormatException:

System.FormatException:值key = XXX'的格式无效。

解决方案是删除等号。

  1. 深入研究反射器显示,在添加新的标头值时会运行大量的验证和解析代码。为什么这一切都是必要的?难道这个客户不应该让我们走开吗?
  2. 如何逃避等号以便添加此值成功?
c# dotnet-httpclient google-cloud-messaging
6个回答
132
投票

不确定是否仍然相关,但我最近遇到了同样的问题,并能够通过调用另一种方法来添加标题信息来解决它:

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

18
投票

对于“为什么所有这些(解析和验证)必要”的问题,答案是:它在HTTP标准中定义。

HTTP/1.1RFC2617中,认证头(例如WWW-Authenticate和Authorization)的值有两部分:方案部分和参数部分。

对于HTTP基本认证,方案是“基本”,参数可能类似于“QWxhZGRpbjpvcGVuIHNlc2FtZQ ==”,因此整个标题变为:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

这就是为什么你的“key = XXX”没有通过验证,因为它缺少一个方案部分。


4
投票

通过以下方式设置Authorization标头,我解决了这个异常(我的FormatException由值中的逗号引起):

var authenticationHeaderValue = new AuthenticationHeaderValue("some scheme", "some value");
client.DefaultRequestHeaders.Authorization = authenticationHeaderValue;

2
投票

当我在Authorization标头的末尾添加一个空格时,我遇到了这个错误并偶然发现了这篇文章。

this.bearerAuthHttpClient.DefaultRequestHeaders.Add("Authorization ", $"Bearer {token}");

您可以在授权后看到违规的“”。

在我看到我的拼写错误之前我花了大约15分钟...


1
投票

今天早上我在处理一个不符合HTTP规范的外部API时遇到了一些问题。

作为我发布的一部分,他们想要Content-TypeContent-Disposition,它们无法添加到HttpClient对象中。要添加这些标题,您需要创建一个HttpRequestMessage。在那里,您需要将标头添加到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
投票

在我的例子中,我从byte [] RowVersion SQL字段生成ETags字符串值。所以我需要添加包装生成。即AAAAAAAAF5s =字符串里面“如下......

        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]);                    
        }
    }
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.