Reputation: 4009
There are many topic but nothing is helpful to me.
I will show you what have I done, and you can tell me what is wrong.
In api I want to desirialize complex object that is send from client:
[HttpPost]
public async Task Post([FromBody]string item)
{
WorkItem data = JsonConvert.DeserializeObject<WorkItem>(item);
//...
}
How I post complex object:
public async Task AddWorkItem()
{
using (var client = HttpClientFactory.GetClient())
{
var item = new WorkItem()
{
Description = DateTime.Now.ToString("h:mm:ss tt"),
Id = 11
};
var inner1 = new ItemUsage()
{
Id = 45,
UsedFor = "something"
};
Collection<ItemUsage> Usage = new Collection<ItemUsage>();
Usage.Add(inner1);
item.Usage = Usage;
string output = JsonConvert.SerializeObject(item);
var response = await client.PostAsync("api/WorkItem", new StringContent(output));
if (!response.IsSuccessStatusCode)
{
throw new Exception((int)response.StatusCode + "-" + response.StatusCode.ToString());
}
}
I get error : 415-UnsupportedMediaType . Maybe my aproach is not best? I need some clean way to post any complex object and my idea is to do this with Json string. What do you think?
Upvotes: 0
Views: 103
Reputation: 4009
Ok it is now clear to me. I will add whole code so that someone else can use it.
[HttpPost]
public async Task Post([FromBody]WorkItem item)
{
//No need to deserialize, you can use item here
}
Call api:
public async Task AddWorkItem()
{
using (var client = HttpClientFactory.GetClient())
{
//Complex object example::
///////////////////
var item = new WorkItem()
{
Description = DateTime.Now.ToString("h:mm:ss tt"),
Id = 11
};
var inner1 = new ItemUsage()
{
Id = 45,
UsedFor = "something"
};
Collection<ItemUsage> Usage = new Collection<ItemUsage>();
Usage.Add(inner1);
item.Usage = Usage;
////////////////////////////
var json = JsonConvert.SerializeObject(item);
var content = new StringContent(json, UnicodeEncoding.UTF8, "application/json");
var response = await client.PostAsync("api/WorkItem", content);
if (!response.IsSuccessStatusCode)
{
throw new Exception((int)response.StatusCode + "-" + response.StatusCode.ToString());
}
}
}
Create client
public static class HttpClientFactory
{
public static HttpClient GetClient()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:1431");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
return client;
}
}
Upvotes: 0
Reputation: 7616
Look like issue is with the datetime serialization. Please see the below answer for help
JsonConvert.SerializeObject vs JsonSerializer.Serialize
Upvotes: 0
Reputation: 84
you are missing one of the key features of WebAPI called model binding or parameter binding. Before the Controller's Action is invoked the incoming data is bound to the Actions parameters. In other words the WebAPI pipeline will handle most deserialization for you. In your example your parameter type is a string, but what you are sending to the server cannot be converted into a string. Supposing the rest of your plumbing is fine, changing the parameter type to WorkItem should do the trick. public async Task Post([FromBody]WorkItem item) If you must accept a string parameter then you must ensure that the body of the request can be converted to a string or write a custom model binder. See here for more info on raw request body handling
Upvotes: 1