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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13198090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 07:44:54  来源:igfitidea点击:

Adding HttpClient headers generates a FormatException with some values

c#dotnet-httpclientgoogle-cloud-messaging

提问by Andrew

This occurred within the context of coding against Google Cloud Messaging, but applies elsewhere.

这发生在针对 Google Cloud Messaging 编码的上下文中,但适用于其他地方。

Consider the following:

考虑以下:

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

and

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

both of which generate a FormatException:

两者都会生成 FormatException:

System.FormatException : The format of value key=XXX' is invalid.

System.FormatException : 值 key=XXX' 的格式无效。

The solution is to remove the equals sign.

解决办法是去掉等号。

  1. Digging into reflector shows there is oodles of validation and parsing code that runs when adding a a new header value. Why is all this necessary? Shouldn't this client just be getting out of our way?

  2. How do you escape the equals sign so that adding this value succeeds?

  1. 深入研究反射器显示,在添加新标头值时,会运行大量验证和解析代码。为什么这一切都是必要的?这个客户不应该让我们挡路吗?

  2. 您如何转义等号,以便成功添加此值?

采纳答案by Antonio

Not sure if still relevant, but I recently ran into this same issue and was able to solve it by calling a different method to add the header information:

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

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

回答by Terry Chang

To your "why is all this (parsing and validation) necessary" question, the answer is: it is defined in the HTTP standard.

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

In HTTP/1.1and RFC2617, the value an authentication header (such as WWW-Authenticate and Authorization) has two parts: a scheme part, and a parameter part.

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

For HTTP Basic Authentication, the scheme is "Basic", and the parameter may be something like "QWxhZGRpbjpvcGVuIHNlc2FtZQ==", so the whole header becomes:

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

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

That's why your "key=XXX" doesn't pass validation, because it lacks a scheme part.

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

回答by CRice

I got around this exception (my FormatException caused by commas in the value) by setting the Authorization header in the following way:

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

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

回答by krillgar

I've been going through a few questions this morning while dealing with an external API that doesn't follow the HTTP spec to the letter.

今天早上我在处理一个不完全遵循 HTTP 规范的外部 API 时遇到了几个问题。

As part of my posting, they want the Content-Typeand Content-Disposition, which cannot be added to the HttpClientobject. To add those headers, you need to create an HttpRequestMessage. On there, you need to add the headers to the Contentproperty.

作为我发布的一部分,他们想要Content-Typeand 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;
}

回答by alhpe

In my case I am generating ETags string values from a byte[] RowVersion SQL field. So I need to add wrap the generated. i.e. AAAAAAAAF5s= string inside " as follows...

就我而言,我从 byte[] RowVersion SQL 字段生成 ETags 字符串值。所以我需要添加 wrap 生成的。即 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]);                    
        }
    }

回答by Robert Stokes

I ran into this error and stumbled on to this post when I added a space to the end of an Authorization header.

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

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

You can see the offending " " after Authorization.

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

It took me about 15 min before I saw my typo...

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