Как отправить произвольные данные JSON с пользовательским заголовком на сервер REST?
TL; DR -- как отправить строку JSON на хост REST с заголовком auth? Я пробовал 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
тип контента неверен при использовании StringContent + 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".
любой пример, если не использовать WebAPI, например servicestack, или что-нибудь еще круто.
2 ответов
/// <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. Похоже, что вы должны указать соответствующую кодировку и тип носителя
вы не можете напрямую настроить экземпляр HttpContent, потому что это абстрактный класс. Вам нужно использовать один из подклассов, в зависимости от ваших потребностей. Скорее всего StringContent, который позволяет установить строковое значение ответа, кодировку и тип носителя в конструкторе:http://msdn.microsoft.com/en-us/library/system.net.http.stringcontent.aspx
ответ как настроить HttpContent для моего HttpClient PostAsync второго параметр?