c# - example - ¿Cómo paso un objeto a HttpClient.PostAsync y lo serializo como un cuerpo JSON?
serializar y deserializar json c# (4)
Estoy usando
System.Net.Http
, encontré varios ejemplos en la web.
Logré crear este código para hacer una solicitud
POST
:
public static string POST(string resource, string token)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(baseUri);
client.DefaultRequestHeaders.Add("token", token);
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("", "")
});
var result = client.PostAsync("", content).Result;
string resultContent = result.Content.ReadAsStringAsync().Result;
return resultContent;
}
}
Todo funciona bien.
Pero supongamos que quiero pasar un tercer parámetro al método
POST
, un parámetro llamado
data
.
El parámetro de datos es un objeto como este:
object data = new
{
name = "Foo",
category = "article"
};
¿Cómo puedo hacer eso sin crear el
KeyValuePair
?
Mi php
RestAPI
espera una entrada json, por lo que
FormUrlEncodedContent
debe enviar el json sin
raw
correctamente.
Pero, ¿cómo puedo hacer esto con
Microsoft.Net.Http
?
Gracias.
Ahora hay una manera más simple con
.NET Standard
o
.NET Core
:
var client = new HttpClient();
var response = await client.PostAsync(uri, myRequestObject, new JsonMediaTypeFormatter());
NOTA:
Para usar la clase
JsonMediaTypeFormatter
, deberá instalar el paquete NuGet de
Microsoft.AspNet.WebApi.Client
, que se puede instalar directamente o mediante otro como
Microsoft.AspNetCore.App
.
Con esta firma de
HttpClient.PostAsync
, puede pasar cualquier objeto y
JsonMediaTypeFormatter
encargará automáticamente de la serialización, etc.
Con la respuesta, puede usar
HttpContent.ReadAsAsync<T>
para deserializar el contenido de la respuesta al tipo que espera:
var responseObject = await response.Content.ReadAsAsync<MyResponseType>();
La respuesta directa a su pregunta es: No. La firma del método
PostAsync
es la siguiente:
Tarea pública PostAsync (Uri requestUri, contenido HttpContent)
Entonces, si bien puede pasar un
object
a
PostAsync
, debe ser del tipo
HttpContent
y su tipo anónimo no cumple con ese criterio.
Sin embargo, hay formas de lograr lo que quieres lograr. Primero, deberá serializar su tipo anónimo a JSON, la herramienta más común para esto es Json.NET . Y el código para esto es bastante trivial:
var myContent = JsonConvert.SerializeObject(data);
A continuación, deberá construir un objeto de contenido para enviar estos datos.
ByteArrayContent
un objeto
ByteArrayContent
, pero podría usar o crear un tipo diferente si lo desea.
var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
var byteContent = new ByteArrayContent(buffer);
A continuación, desea establecer el tipo de contenido para que la API sepa que esto es JSON.
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
Luego puede enviar su solicitud de manera muy similar a su ejemplo anterior con el contenido del formulario:
var result = client.PostAsync("", byteContent).Result
En una nota al margen, llamar a la propiedad
.Result
como lo está haciendo aquí puede tener algunos
efectos secundarios negativos
, como bloqueo muerto, por lo que debe tener cuidado con esto.
Una solución simple es usar
Microsoft ASP.NET Web API 2.2 Client
de
NuGet
.
Luego, simplemente puede hacer esto y serializará el objeto en JSON y establecerá el encabezado
Content-Type
en
application/json; charset=utf-8
application/json; charset=utf-8
:
var data = new
{
name = "Foo",
category = "article"
};
var client = new HttpClient();
client.BaseAddress = new Uri(baseUri);
client.DefaultRequestHeaders.Add("token", token);
var response = await client.PostAsJsonAsync("", data);
FormUrlEncodedContent
pasar sus datos en el cuerpo de la solicitud como una cadena sin
FormUrlEncodedContent
lugar de
FormUrlEncodedContent
.
Una forma de hacerlo es serializarlo en una cadena JSON:
var json = JsonConvert.SerializeObject(data);
Ahora todo lo que necesita hacer es pasar la cadena al método de publicación.
var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json");
var client = new HttpClient();
var response = await client.PostAsync(uri, stringContent);