[c#] HttpClient 헤더를 추가하면 일부 값이 포함 된 FormatException이 생성됩니다.

이는 Google 클라우드 메시징에 대한 코딩 컨텍스트 내에서 발생했지만 다른 곳에 적용됩니다.

다음을 고려하세요:

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. 이 값을 성공적으로 추가하려면 등호를 어떻게 이스케이프합니까?



답변

여전히 관련성이 있는지 확실하지 않지만 최근에 동일한 문제가 발생하여 헤더 정보를 추가하는 다른 메서드를 호출하여 해결할 수있었습니다.

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


답변

“이 모든 것 (파싱 및 유효성 검사)이 필요한 이유”에 대한 대답은 HTTP 표준에 정의되어 있습니다.

에서는 HTTP / 1.1RFC2617 : 값 (예를 들면 WWW 인증 및 허가와 같은) 인증 헤더는 두 부분으로 갖는 스킴 부와 파라미터 부를 .

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-TypeContent-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 문자열 값을 생성하고 있습니다. 그래서 생성 된 랩을 추가해야합니다. ie 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]);
        }
    }


답변