ChatGPT解决这个技术问题 Extra ChatGPT

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

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

解决方案是删除等号。

深入研究反射器显示在添加新标头值时会运行大量验证和解析代码。为什么这一切都是必要的?这个客户不应该让我们走开吗?您如何转义等号以便添加此值成功?

@SamIam 试图将消息发布到 GCN API - 这需要使用上面显示的格式将身份验证信息作为标头发送。但是,这是关于 HttpClient 标头的允许值的更普遍的问题。

A
Antonio

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

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

如果您不希望在默认标头中使用此方法,也可以在 HttpRequestMessage 上调用此方法
将此标记为答案,即使我仍然不明白为什么其他方法在验证时失败(如果它是有效值)。
此外,在 Windows 10 的 httpclient 中似乎没有帮助
我看到这是一个旧线程,但我刚刚遇到了这个问题@EdSykes 并尝试使用 HttpRequestMessage 来代替它并没有任何区别。 TryAddWithoutValidation 方法对我有用。
我的问题是关于 User-Agent 标头,但感谢您指向 TryAddWithoutValidation
G
Guanxi

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

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

对于 HTTP Basic Authentication,scheme 是“Basic”,参数可能类似于“QWxhZGRpbjpvcGVuIHNlc2FtZQ==”,所以整个 header 变成:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

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


在参数部分有 key=value 是有效的。请参阅stackoverflow.com/a/19512506/55732
@Kurlak:key=value 仅对“auth-param”部分有效,对整个“credentials”部分无效。 CodeCaster 的解释不太对。
我实际上使用 Bearer 作为方案,但它仍然向我显示错误。
我在 Bearer 之后有一个空格,比如“Bearer”,这引起了问题。我在下面看到了@Robert Stokes 的回答,帮助我看到了它。
key=XXX 可能无效,但它仍然是 Google Firebase API 对您的期望:(( 证明:firebase.google.com/docs/cloud-messaging/…
R
Robert Stokes

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

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

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

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


C
CRice

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

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

k
krillgar

今天早上我在处理一个不完全遵循 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;
}

a
alhpe

在我的例子中,我从 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]);                    
        }
    }