これは、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 'の形式が無効です。
解決策は、等号を削除することです。
リフレクターを掘り下げると、新しいヘッダー値を追加するときに実行される検証および解析コードがたくさんあることがわかります。なぜこれがすべて必要なのですか?このクライアントは私たちの邪魔をするべきではありませんか?
この値の追加が成功するように、等号をどのようにエスケープしますか?
関連するかどうかはわかりませんが、最近この同じ問題に遭遇し、別のメソッドを呼び出してヘッダー情報を追加することで解決できました。
var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "key=XXX");
「なぜこの(解析と検証)が必要なのか」という質問に対する答えは、HTTP標準で定義されています。
HTTP/1.1 および RFC2617 では、認証ヘッダー(WWW-AuthenticateやAuthorizationなど)の値には2つの部分があります:a scheme part、およびパラメーターpart。
HTTP基本認証の場合、スキームは「Basic」であり、パラメーターは "QWxhZGRpbjpvcGVuIHNlc2FtZQ =="のようになる可能性があるため、ヘッダー全体は次のようになります。
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
そのため、スキーム部分がないため、「key = XXX」は検証に合格しません。
Authorizationヘッダーを次のように設定することで、この例外(値のコンマが原因のFormatException)を回避しました。
var authenticationHeaderValue = new AuthenticationHeaderValue("some scheme", "some value");
client.DefaultRequestHeaders.Authorization = authenticationHeaderValue;
Authorizationヘッダーの最後にスペースを追加すると、このエラーに遭遇し、この投稿につまずきました。
this.bearerAuthHttpClient.DefaultRequestHeaders.Add("Authorization ", $"Bearer {token}");
認証後に問題のある「」を確認できます。
タイプミスを見るまでに約15分かかりました...
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文字列値を生成しています。そのため、生成されたラップを追加する必要があります。つまり、AAAAAAAAF5s = string within "次のように...
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]);
}
}