사용자 정의 헤더와 함께 임의의 JSON 데이터를 휴식 서버에 어떻게 보내는가?
-
22-12-2019 - |
문제
tl; DR - 인증 헤더가있는 REST 호스트에 JSON 문자열을 어떻게 보낼 수 있습니까? 나는 익명의 종류와 함께 작동하는 3 가지 접근 방식을 발견했습니다. 왜 익명 유형을 사용할 수 없습니까? "group-name"이라는 변수를 설정해야하며 하이픈은 유효한 C # 식별자가 아닙니다.
배경
JSON을 게시해야하지만 시체와 콘텐츠 유형을 올바르게 사용할 수 없습니다
기능 # 1 - 익명 유형
에서 작동합니다콘텐츠 유형과 데이터가 올바르지 만 익명 유형을 사용하지 않으려 고합니다. 문자열을 사용하고 싶습니다
static void PostData(string restURLBase, string RESTUrl, string AuthToken, string postBody)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(restURLBase);
client.DefaultRequestHeaders.Add("Auth-Token", AuthToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// StringContent content = new StringContent(postBody);
var test1 = "data1";
var test2 = "data2";
var test3 = "data3";
var response = client.PostAsJsonAsync(RESTUrl, new { test1, test2, test3}).Result; // Blocking call!
if (!response.IsSuccessStatusCode)
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
return;
}
}
.
출력 # 1
콘텐츠 형식과 데이터는 anonymoustypes + postasjsonasync를 사용할 때 올바른지 만 익명 유형을 사용하지 않으려면
POST https://api.dynect.net/REST/Zone/ABCqqqqqqqqqqqqYYYYYtes3ss.com HTTP/1.1
Auth-Token: --- REDACTED -----
Accept: application/json
Content-Type: application/json; charset=utf-8
Host: api.dynect.net
Content-Length: 49
Expect: 100-continue
{"test1":"data1","test2":"data2","test3":"data3"}
.
기능 # 2 - 예상대로 작동하지 않습니다
문자열을 가져 와서 StringContent 객체에 넣으십시오. 이는 콘텐츠 유형을 변경하는 부작용이 있습니다.
static void PostData(string restURLBase, string RESTUrl, string AuthToken, string postBody)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(restURLBase);
client.DefaultRequestHeaders.Add("Auth-Token", AuthToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
StringContent content = new StringContent(postBody);
var response = client.PostAsync(RESTUrl, content).Result; // Blocking call!
if (!response.IsSuccessStatusCode)
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
return;
}
}
.
출력 # 2
content_content + postasync
를 사용할 때 콘텐츠 유형이 잘못되었습니다.POST https://api.dynect.net/REST/Zone/ABCqqqqqqqqqqqqYYYYYtes3ss.com HTTP/1.1
Auth-Token: ---- REDACTED -------
Accept: application/json // CORRECT
Content-Type: text/plain; charset=utf-8 // WRONG!!!
Host: api.dynect.net
Content-Length: 100
Expect: 100-continue
{"rdata" : ["rname" : "dynect.nfp.com", "zone" : "ABCqqqqqqqqqqqqYYYYYtes3ss.com"], "ttl" : "43200"}
// ^^ THIS IS CORRECT
.
기능 # 3 - 예상대로 작동하지 않습니다
PostAsJsonAsync
가 ContentType을 올바르게 설정하면 해당 방법을 사용할 수 있습니다. (작동하지 않음)
static void PostData(string restURLBase, string RESTUrl, string AuthToken, string postBody)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(restURLBase);
client.DefaultRequestHeaders.Add("Auth-Token", AuthToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
StringContent content = new StringContent(postBody);
var response = client.PostAsJsonAsync(RESTUrl, content).Result; // Blocking call!
if (!response.IsSuccessStatusCode)
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
return;
}
}
.
출력 # 3
콘텐츠 유형이 정확하고, StringContent + PostAsjsonAsync
를 사용할 때 게시물이 잘못되었습니다.POST https://api.dynect.net/REST/Zone/ABCqqqqqqqqqqqqYYYYYtes3ss.com HTTP/1.1
Auth-Token: -- REDACTED ---
Accept: application/json
Content-Type: application/json; charset=utf-8
Host: api.dynect.net
Content-Length: 74
Expect: 100-continue
{"Headers":[{"Key":"Content-Type","Value":["text/plain; charset=utf-8"]}]}
.
질문
제가 원하는 것은 JSON을 문자열로 보내거나 런타임에 정의 된 동적 객체, HTTP 콘텐츠 유형이 올바른 및 특수 'auth-token'헤더를 사용하여 서버에 보내는 것입니다.
모든 예제, ServiceStack과 같은 WebApi를 사용하지 않거나 다른 것이 멋지다.
해결책
/// <summary>
/// Creates a new instance of the <see cref="T:System.Net.Http.StringContent"/> class.
/// </summary>
/// <param name="content">The content used to initialize the <see cref="T:System.Net.Http.StringContent"/>.</param><param name="encoding">The encoding to use for the content.</param><param name="mediaType">The media type to use for the content.</param>
[__DynamicallyInvokable]
public StringContent(string content, Encoding encoding, string mediaType)
: base(StringContent.GetContentByteArray(content, encoding))
{
this.Headers.ContentType = new MediaTypeHeaderValue(mediaType == null ? "text/plain" : mediaType)
{
CharSet = encoding == null ? HttpContent.DefaultStringEncoding.WebName : encoding.WebName
};
}
.
StringContent의 생성자입니다.적절한 인코딩 및 MediaType
를 지정 해야하는 것처럼 보입니다.다른 팁
추상 클래스이기 때문에 HttpContent의 인스턴스를 직접 설정할 수 없습니다.필요에 따라 하위 클래스 중 하나를 사용해야합니다.대부분의 문자열은 응답의 문자열 값, 인코딩 및 생성자의 미디어 유형을 설정할 수 있습니다. http://msdn.microsoft.com/en-us/library/system.net.http.stringContent.aspx