Estoy usando System.Net.Http
, encontré varios ejemplos en la web. Logré crear este código para hacer una POST
solicitud:
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 POST
método, 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
debería enviar el raw
json correctamente. ¿Pero cómo puedo hacer esto con Microsoft.Net.Http
? Gracias.
c#
json
dotnet-httpclient
IlDrugo
fuente
fuente
using
paraHttpClient
. aspnetmonsters.com/2016/08/2016-08-27-httpclientwrongusing
qué no se debe utilizar:HttpClient is intended to be instantiated once and reused throughout the life of an application. The following conditions can result in SocketException errors: Creating a new HttpClient instance per request. Server under heavy load. Creating a new HttpClient instance per request can exhaust the available sockets.
docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/…Respuestas:
La respuesta directa a su pregunta es: No. La firma del
PostAsync
método es la siguiente:Entonces, si bien puede pasar un
object
aPostAsync
, debe ser de tipoHttpContent
y su tipo anónimo no cumple con ese criterio.Sin embargo, hay formas de lograr lo que desea lograr. Primero, necesitará 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, usaré un
ByteArrayContent
objeto, pero puede 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 configurar el tipo de contenido para que la API sepa que se trata de 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
.Result
propiedad como lo está haciendo aquí puede tener algunos efectos secundarios negativos , como bloqueo muerto, por lo que debe tener cuidado con esto.fuente
POST, PUT, DELETE
se realiza un, generalmente el retorno de la APITRUE
, declaro el método comostring
, pero cuando lo hago:return result;
obtengo:,Can't Convert HttpResponseMessage in string
¿debo cambiar la declaración del método? Necesito la respuesta de cadena porque necesitaré deserializarla después en otro método de clase.result.Content.ReadAsStringAsync()
) probablemente esté bien. Dependiendo de la estructura de su aplicación, podría ser mejor devolver elContent
objeto directamente si necesita inspeccionar los encabezados para determinar cuál es el tipo de contenido (por ejemplo, XML o JSON). Pero si sabe que siempre devolverá JSON (o algún otro formato), simplemente devolver el cuerpo de la respuesta como una cadena debería estar bien.StringContent
?StringContent
directamente aPostAsync
ya que se deriva deHttpContent
.Debe pasar sus datos en el cuerpo de la solicitud como una cadena sin formato en lugar de
FormUrlEncodedContent
. Una forma de hacerlo es serializarlo en una cadena JSON:var json = JsonConvert.SerializeObject(data); // or JsonSerializer.Serialize if using System.Text.Json
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"); // use MediaTypeNames.Application.Json in Core 3.0+ and Standard 2.1+ var client = new HttpClient(); var response = await client.PostAsync(uri, stringContent);
fuente
stringContent
? En mi caso elstringContent
valor es"\"\""
. ¿Es este el valor correcto?Una solución simple es usar
Microsoft ASP.NET Web API 2.2 Client
desde NuGet .Luego, simplemente puede hacer esto y serializará el objeto en JSON y establecerá el
Content-Type
encabezado enapplication/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);
fuente
Ahora hay una forma más sencilla con
.NET Standard
o.NET Core
:var client = new HttpClient(); var response = await client.PostAsync(uri, myRequestObject, new JsonMediaTypeFormatter());
NOTA: Para usar la
JsonMediaTypeFormatter
clase, deberá instalar elMicrosoft.AspNet.WebApi.Client
paquete NuGet, que se puede instalar directamente o mediante otro comoMicrosoft.AspNetCore.App
.Con esta firma de
HttpClient.PostAsync
, puede pasar cualquier objeto yJsonMediaTypeFormatter
automáticamente se encargará 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>();
fuente
.NET Standard
o.NET Core
, como mencioné. ¿Quizás estás usando.NET Framework
? En mi proyecto, JsonMediaTypeFormatter se carga desde aquí: C: \ Archivos de programa \ dotnet \ sdk \ NuGetFallbackFolder \ microsoft.aspnet.webapi.client \ 5.2.6 \ lib \ netstandard2.0 \ System.Net.Http.Formatting. dll