How to Use System.Net.Httpclient to Post a Complex Type

How to use System.Net.HttpClient to post a complex type?

The generic HttpRequestMessage<T> has been removed. This :

new HttpRequestMessage<Widget>(widget)

will no longer work.

Instead, from this post, the ASP.NET team has included some new calls to support this functionality:

HttpClient.PostAsJsonAsync<T>(T value) sends “application/json”
HttpClient.PostAsXmlAsync<T>(T value) sends “application/xml”

So, the new code (from dunston) becomes:

Widget widget = new Widget()
widget.Name = "test"
widget.Price = 1;

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:44268");
client.PostAsJsonAsync("api/test", widget)
.ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode() );

How to send a complex object using Get with c# HttpClient

You can use Reflection:

public IEnumerable<string> ToQueryStringItem<T>(T entity)
{
foreach(var pi in typeof(T).GetProperties())
yield return $"{pi.Name}={pi.GetValue(entity)}";
}

public IEnumerable<string> ToQueryString<T>(T entity)
=> $"?{string.Join("&", ToQueryString(entity).ToList())}";

now simply you can do it like:

string qs = ToQueryString(someClassInstance);

Please note that if the class properties are not of primitive types, you will need a more complex code for reflection.

And also if you want some customized values it will also be doable, for instance lets say instead of true and false, you want 1 and 0:

foreach(var pi in typeof(T).GetProperties())
{
switch(pi.PropertyType.ToString())
{
case "Boolean":
yield return $"{pi.Name}={(pi.GetValue(entity)?1:0)};
//....
default:
yield return $"{pi.Name}={pi.GetValue(entity)}";
}
}

You may also want to hide some properties from being used in query string, for that you can create an attribute:

public class IgnoreInQueryStringAttribute: Attribute {}

and use it for any property you don't want to be in the query string:

public class Customer
{
[IgnoreInQueryString]
public int Id { get; set; }
public string Firstname { get; set; }
}

and then:

foreach(var pi in typeof(T).GetProperties())
{
if(pi.GetCustomAttributes(typeof(IgnoreInQueryString), false).Length == 0)
{
//....
}
}

Post complex data type using HttpClient

By converting the object into a json string you can transfer the json object.

You can use the JavaScriptSerializer class:

using System.Web.Script.Serialization;
var json = new JavaScriptSerializer().Serialize(obj);

Then you can return the object from webapi.

How do I pass an object to HttpClient.PostAsync and serialize as a JSON body?

The straight up answer to your question is: No. The signature for the PostAsync method is as follows:

public Task PostAsync(Uri requestUri, HttpContent content)

So, while you can pass an object to PostAsync it must be of type HttpContent and your anonymous type does not meet that criteria.

However, there are ways to accomplish what you want to accomplish. First, you will need to serialize your anonymous type to JSON, the most common tool for this is Json.NET. And the code for this is pretty trivial:

var myContent = JsonConvert.SerializeObject(data);

Next, you will need to construct a content object to send this data, I will use a ByteArrayContent object, but you could use or create a different type if you wanted.

var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
var byteContent = new ByteArrayContent(buffer);

Next, you want to set the content type to let the API know this is JSON.

byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

Then you can send your request very similar to your previous example with the form content:

var result = client.PostAsync("", byteContent).Result

On a side note, calling the .Result property like you're doing here can have some bad side effects such as dead locking, so you want to be careful with this.

How to pass complex type using httpClient with DeleteAsync?

You could use httpPost to post your complex object to your delete method.

E.g.

[System.Web.Http.AcceptVerbs("Post")]
public HttpResponseMessage DeleteComplexObject(Models.ComplexObject deleteme)
{
this.ComplexObjectService.Delete(deleteme);
var response = Request.CreateResponse(HttpStatusCode.Accepted);

return response;
}

Here model binding is used to convert your json object into the ComplexObject automatically so you don't need to use [FromBody]

Send HTTP POST message in ASP.NET Core using HttpClient PostAsJsonAsync

You should add reference to "Microsoft.AspNet.WebApi.Client" package (read this article for samples).

Without any additional extension, you may use standard PostAsync method:

client.PostAsync(uri, new StringContent(jsonInString, Encoding.UTF8, "application/json"));

where jsonInString value you can get by calling JsonConvert.SerializeObject(<your object>);

POSTing JsonObject With HttpClient From Web API

With the new version of HttpClient and without the WebApi package it would be:

var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");
var result = client.PostAsync(url, content).Result;

Or if you want it async:

var result = await client.PostAsync(url, content);


Related Topics



Leave a reply



Submit