95

这发生在针对 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 : value key=XXX' 的格式无效。

解决方案是删除等号。

  1. 深入研究反射器显示在添加新标头值时会运行大量验证和解析代码。为什么这一切都是必要的?这个客户不应该让我们走开吗?

  2. 您如何转义等号以便添加此值成功?

4

6 回答 6

214

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

var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "key=XXX");
于 2013-03-06T08:12:02.250 回答
27

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

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

对于 HTTP 基本身份验证,方案为“基本”,参数可能类似于“QWxhZGRpbjpvcGVuIHNlc2FtZQ==”,因此整个标头变为:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

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

于 2015-04-12T07:53:43.097 回答
9

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

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

您可以在授权后看到有问题的“ ”。

我花了大约 15 分钟才看到我的错字...

于 2019-03-12T17:46:06.360 回答
8

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

var authenticationHeaderValue = new AuthenticationHeaderValue("some scheme", "some value");
client.DefaultRequestHeaders.Authorization = authenticationHeaderValue;
于 2015-12-23T05:39:52.607 回答
1

今天早上我在处理一个不完全遵循 HTTP 规范的外部 API 时遇到了几个问题。

作为我发布的一部分,他们想要Content-Typeand Content-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;
}
于 2017-07-11T12:05:29.333 回答
0

在我的例子中,我从 byte[] RowVersion SQL 字段生成 ETags 字符串值。所以我需要添加 wrap 生成的。即 AAAAAAAAF5s= string inside " 如下...

        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]);                    
        }
    }
于 2018-09-17T13:14:26.413 回答