web-dev-qa-db-ja.com

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:値key = XXX 'の形式が無効です。

解決策は、等号を削除することです。

  1. リフレクターを掘り下げると、新しいヘッダー値を追加するときに実行される検証および解析コードがたくさんあることがわかります。なぜこれがすべて必要なのですか?このクライアントは私たちの邪魔をするべきではありませんか?

  2. この値の追加が成功するように、等号をどのようにエスケープしますか?

61
Andrew

関連するかどうかはわかりませんが、最近この同じ問題に遭遇し、別のメソッドを呼び出してヘッダー情報を追加することで解決できました。

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

「なぜこの(解析と検証)が必要なのか」という質問に対する答えは、HTTP標準で定義されています。

HTTP/1.1 および RFC2617 では、認証ヘッダー(WWW-AuthenticateやAuthorizationなど)の値には2つの部分があります:a scheme part、およびパラメーターpart

HTTP基本認証の場合、スキームは「Basic」であり、パラメーターは "QWxhZGRpbjpvcGVuIHNlc2FtZQ =="のようになる可能性があるため、ヘッダー全体は次のようになります。

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

そのため、スキーム部分がないため、「key = XXX」は検証に合格しません。

18
Terry Chang

Authorizationヘッダーを次のように設定することで、この例外(値のコンマが原因のFormatException)を回避しました。

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

Authorizationヘッダーの最後にスペースを追加すると、このエラーに遭遇し、この投稿につまずきました。

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

認証後に問題のある「」を確認できます。

タイプミスを見るまでに約15分かかりました...

2
Robert Stokes

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;
}
1
krillgar

私の場合、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]);                    
        }
    }
0
alhpe