how to save an object using .net webapi
Solution 1
I think I found the solution thats why I'm posting this as answer not comment so any later discussion could be grouped.
If I send request like this
using(HttpClient client = new HttpClient()) {
await client.PostAsync(uri, new StringContent("my own string");
}
Than I can get it in my webapi from
await Request.Content.ReadAsStringAsync();
IMO this is not perfect solution but at least I'm on trace. I see that params from function definitione I can get only if they are in URL even when I send a POST request.
Probably this solution also will work (i didn't check it yet) when I use more complex objects then String.
ANy thoughts from someone. Do you think that this is good solution ?
Solution 2
WebAPI is really good at parsing data sent to it and converting it to .NET objects.
I am not used to using a C# client with WebAPI, but I'd try the following:
var client = new HttpClient();
client.PostAsJsonAsync<YourObjectType>("uri", yourObject);
Note: You need to use System.Net.Http
(from assembly with the same name) as well as System.Net.Http.Formatting
(also from assembly with the same name) for this.
Solution 3
The HttpRequestMessage
class has a property named Content
which is type of HttpContent
(an abstract class). You can set the request body there. For example, you can set the JSON content there and then send it to the API:
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri) {
Content = new StringContent("{'Name':'Foo', 'Surname':'Bar'}")
};
You can also use the formatting feature and supply your CLR object to ObjectContent
and delegate the serialization to the Formatter.
There are lots of samples on HttpClient and Web API here: http://blogs.msdn.com/b/henrikn/archive/2012/07/20/asp-net-web-api-sample-on-codeplex.aspx
Solution 4
Assuming you have an action method on your web API controller that supports a POST operation that is similiar to:
[HttpPost()]
public HttpResponseMessage Post(YourObjectType value)
{
try
{
var result = this.Repository.Add(value);
var response = this.Request.CreateResponse<YourObjectType>(HttpStatusCode.Created, result);
if (result != null)
{
var uriString = this.Url.Route(null, new { id = result.Id });
response.Headers.Location = new Uri(this.Request.RequestUri, new Uri(uriString, UriKind.Relative));
}
return response;
}
catch (ArgumentNullException argumentNullException)
{
throw new HttpResponseException(
new HttpResponseMessage(HttpStatusCode.BadRequest)
{
ReasonPhrase = argumentNullException.Message.Replace(Environment.NewLine, String.Empty)
}
);
}
}
You can use the HttpClient to serialize your object to JSON and POST the content to you controller method:
using (var client = new HttpClient())
{
client.BaseAddress = baseAddress;
client.Timeout = timeout;
using (var response = client.PostAsJsonAsync<YourObjectType>("controller_name", yourObject).Result)
{
if (!response.IsSuccessStatusCode)
{
// throw an appropriate exception
}
result = response.Content.ReadAsAsync<YourObjectType>().Result;
}
}
- The NuGet package for ASP.NET MVC 4 (which provides you with the web API framework) is available at http://nuget.org/packages/AspNetMvc.
- The Web API reference at http://msdn.microsoft.com/en-us/library/hh849329(v=vs.108).aspx.
I would also recommend taking a look at Creating a Web API that Supports CRUD Operations, which covers the scenarios you are describing, specifically the Creating a Resource section.
Solution 5
I hope this would be what you are looking for.
I created a generic Post that will accept any object and post it
Client Side
public async Task<HttpResponseMessage> Post<T>(string requestUri, T newObject) where T : class
{
using (var client = new HttpClient())
{
client.BaseAddress = this.HttpClientAddress;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = JsonConvert.SerializeObject(newObject, this.JsonSerializerSettings);
var clientAsync = await client.PostAsync(requestUri, new StringContent(content, Encoding.UTF8, "application/json"));
clientAsync.EnsureSuccessStatusCode();
return clientAsync;
}
}
the call to this will be as simple as
public async Task<int> PostPerson(Models.Person person)
{
//call to the generic post
var response = await this.Post("People", person);
//get the new id from Uri api/People/6 <-- this is generated in the response after successful post
var st = response.Headers.Location.Segments[3];
//do whatever you want with the id
return response.IsSuccessStatusCode ? JsonConvert.DeserializeObject<int>(st) : 0;
}
Also, you can read the object after the post using ReadAsStringAsync() if your usecase requires so.
Server Side
// POST: api/People
public IHttpActionResult Post(Models.Person personDto)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var person = new Entities.Person
{
FirstName = personDto.FirstName,
LastName = personDto.LastName,
DateOfBirth = personDto.DateOfBirth,
PreferedLanguage = personDto.PreferedLanguage
};
_db.Persons.Add(person);
_db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = person.Id }, personDto);
}
Comments
-
Fixus almost 2 years
I've create WebAPI in .net (my first). Using this api to get object from db, query db etc is easy for me. Nothing new
But I'm wondering how to save an object using this webapi ?
I have a clinet application (tablet, phone, PC) that communicates with my webapi. From my application there is an possibility to save a user news. Now I need to save it in db. I use Azure SQL. Now how can I pass this object to API so I can save it ?
For my application I use C#/XAML For my WebAPI I use .NET
I'm tring with this code:
HttpClient httpClient = new HttpClient(); String u = this.apiUrl + "sd/Localization/insert"; Uri uri = new Uri(u); HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, uri);
But I don't know how to send object ? Should I serialize it ? If yes how to send it via post.
// UPDATE
I've constructed this
HttpClient httpClient = new HttpClient(); String u = this.apiUrl + "sd/Localization/insert"; Uri uri = new Uri(u); HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, uri); httpRequestMessage.Content = new StringContent("{'Name':'Foo', 'Surname':'Bar'}"); await httpClient.PostAsync(uri, httpRequestMessage.Content);
But in my API the variable is null
This is code from my api
// POST sd/Localization/insert public void Post(string test) { Console.WriteLine(test); }
The "test" variable is null. What am I doing wrong ?
// UPDATE 2
using (HttpClient httpClient = new HttpClient()) { String u = this.apiUrl + "sd/Localization/insert"; Uri uri = new Uri(u); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri) { Method = HttpMethod.Post, Content = new StringContent("my own test string") }; await httpClient.PostAsync(uri, request.Content); }
Routing config
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "sd/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }
after all your answers I've created this but still I get null on param in my api. Where is the mistake ?