¿Cómo puedo enviar arbitraria de datos JSON, con un encabezado personalizado, a un DESCANSO servidor?
-
22-12-2019 - |
Pregunta
TL;DR: ¿Cómo puedo enviar una cadena JSON a un RESTO de host con un encabezado de autenticación?Yo he probado 3 diferentes enfoques encontrado uno que funciona con los tipos anónimos.Por qué no puedo usar los tipos anónimos?Tengo que crear una variable llamada "Nombre del Grupo", y un guión no es válida C# identificador.
De fondo
Necesito POST JSON pero soy incapaz de conseguir el cuerpo y el tipo de contenido correcto
Función #1 - Funciona con los tipos anónimos
El tipo de contenido y los datos son correctos, pero no quiero usar los tipos anónimos.Quiero usar una cadena
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;
}
}
Salida #1
El tipo de contenido y de datos es correcta cuando se utiliza AnonymousTypes + PostAsJsonAsync, pero no quiero usar los tipos anónimos.
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"}
Función #2 - no funciona como se esperaba
Toma una cadena y lo puso en una StringContent objeto.Esto tiene un efecto secundario de cambiar el tipo de contenido.
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;
}
}
Salida #2
El tipo de contenido que es incorrecto el uso de 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
Función #3 - no funciona como se esperaba
Desde que me conozco PostAsJsonAsync
establece el contentType correctamente, permite el uso de ese método.(no funciona)
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;
}
}
Salida #3
Tipo de contenido es correcto, cuerpo del POST está mal cuando se utiliza 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"]}]}
Pregunta
Todo lo que quiero hacer es enviar JSON como una cadena, o un objeto dinámico que se define en tiempo de ejecución, para un servidor, con el tipo de contenido HTTP correcta, y con un especial de 'Auth Token' encabezado.
Cualquier ejemplo, si no se utiliza WebAPI, tales como servicestack, o cualquier otra cosa, es genial.
Solución
/// <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
};
}
Es constructor de StringContent.Parece que usted debe especificar la Codificación adecuada y mediaType
Otros consejos
No se puede directamente la instalación de una instancia de HttpContent, porque es una clase abstracta.Usted necesidad de utilizar una de las sub-clases, dependiendo de su necesidad.Lo más probable StringContent, que permite establecer la cadena de valor de la respuesta, la codificación, y el tipo de medio en el constructor: http://msdn.microsoft.com/en-us/library/system.net.http.stringcontent.aspx
Respuesta de ¿Cómo puedo configurar HttpContent para mi HttpClient PostAsync segundo parámetro?