Добавление заголовков 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: формат значения ключ =XXX'недопустим.
Решение состоит в том, чтобы удалить знак равенства.
Копание в отражатель показывает, что существует множество кодов проверки и анализа, которые запускаются при добавлении нового значения заголовка. Зачем все это нужно? Разве этот клиент не должен просто уйти с нашего пути?
Как вы избегаете знака равенства, чтобы добавить это значение успешно?
5 ответов
Не уверен, что все еще актуален, но я недавно столкнулся с этой же проблемой и смог решить ее, вызвав другой метод для добавления информации заголовка:
var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "key=XXX");
На ваш вопрос "зачем все это (разбор и проверка)" нужен ответ: он определен в стандарте HTTP.
В HTTP/1.1 и RFC2617 значение заголовка аутентификации (такого как WWW-Authenticate и Authorization) состоит из двух частей: части схемы и части параметров.
Для базовой аутентификации HTTP используется схема "Базовая", а параметр может быть что-то вроде "QWxhZGRpbjpvcGVuIHNlc2FtZQ ==", поэтому весь заголовок становится:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Вот почему ваш "ключ =XXX" не проходит проверку, потому что в нем отсутствует часть схемы.
Я столкнулся с этой ошибкой и наткнулся на этот пост, когда добавил пробел в конец заголовка авторизации.
this.bearerAuthHttpClient.DefaultRequestHeaders.Add("Authorization ", $"Bearer {token}");
Вы можете увидеть оскорбительные " " после авторизации.
Мне понадобилось около 15 минут, прежде чем я увидел свою опечатку...
Я обошел это исключение (мое исключение FormatException, вызванное запятыми в значении), установив заголовок Authorization следующим образом:
var authenticationHeaderValue = new AuthenticationHeaderValue("some scheme", "some value");
client.DefaultRequestHeaders.Authorization = authenticationHeaderValue;
Сегодня утром я разобрался с несколькими вопросами, имея дело с внешним API, который не соответствует спецификации HTTP к письму.
Как часть моей публикации, они хотят 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;
}
В моем случае я генерирую строковые значения ETags из поля SQL byte[] RowVersion. Поэтому мне нужно добавить обтекание сгенерированного. т.е. 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]);
}
}