这发生在针对 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' 的格式无效。
解决方案是删除等号。
深入研究反射器显示在添加新标头值时会运行大量验证和解析代码。为什么这一切都是必要的?这个客户不应该让我们走开吗?您如何转义等号以便添加此值成功?
不确定是否仍然相关,但我最近遇到了同样的问题,并且能够通过调用不同的方法来添加标题信息来解决它:
var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "key=XXX");
对于您的“为什么所有这些(解析和验证)都是必要的”问题,答案是:它是在 HTTP 标准中定义的。
在 HTTP/1.1 和 RFC2617 中,身份验证标头(例如 WWW-Authenticate 和 Authorization)的值有两部分:方案部分和参数部分。
对于 HTTP Basic Authentication,scheme 是“Basic”,参数可能类似于“QWxhZGRpbjpvcGVuIHNlc2FtZQ==”,所以整个 header 变成:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
这就是为什么您的“key=XXX”没有通过验证的原因,因为它缺少方案部分。
Bearer
作为方案,但它仍然向我显示错误。
key=XXX
可能无效,但它仍然是 Google Firebase API 对您的期望:(( 证明:firebase.google.com/docs/cloud-messaging/…
当我在 Authorization 标头的末尾添加一个空格时,我遇到了这个错误并偶然发现了这篇文章。
this.bearerAuthHttpClient.DefaultRequestHeaders.Add("Authorization ", $"Bearer {token}");
您可以在授权后看到有问题的“ ”。
我花了大约 15 分钟才看到我的错字...
我通过以下方式设置 Authorization 标头解决了这个异常(我的 FormatException 由值中的逗号引起):
var authenticationHeaderValue = new AuthenticationHeaderValue("some scheme", "some value");
client.DefaultRequestHeaders.Authorization = authenticationHeaderValue;
今天早上我在处理一个不完全遵循 HTTP 规范的外部 API 时遇到了几个问题。
作为我发布的一部分,他们需要 Content-Type
和 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;
}
在我的例子中,我从 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]);
}
}
不定期副业成功案例分享
HttpRequestMessage
来代替它并没有任何区别。TryAddWithoutValidation
方法对我有用。User-Agent
标头,但感谢您指向TryAddWithoutValidation
。