returnRequest.CreateErrorResponse(HttpStatusCode.BadRequest,"Could not save to the database.");

}

}

catch(Exception ex)

{

returnRequest.CreateErrorResponse(HttpStatusCode.BadRequest,ex);

}

}

In the above implementation we’ve to note four things:

Method named is “Post”, so the clients needs to issue HTTP Post request.

The method accepts parameter of type CourseModel, in Web API parameters with complex types are deserialized from the request body. So the client has to send a serialized representation of a CourseModel object in JSON format.

We’ve returned proper “HttpResponseMessange” for all possible scenarios that might happen when we execute this operation. In case the resource is created successfully, server should return HTTP response 201(Resource Created) along with the resource created. It is very important to return the resource created in response message because it will contain CourseId generated at the server.

We’ve introduced method named “Parse” in “ModelFactory” class which is responsible to parse the “CourseModel” back to the “Course” domain model object which can be added to our repository. You can use GitHub to browse the latest version of “ModelFactory” and “BaseApiController” classes in order to check the changes introduced to apply “Parse” function.

To test this we need to open fiddler and choose the Composer tab, we’ll issue a POST request to the URI: http://localhost:{your_port}/api/courses/The request will look as the image below:

In this HTTP POST request we need to note the following:

The “content-type” header is set to “application/json” because we are sending JSON data in request body.

The “accept” header is set to “application/json” because we are returning response in JSON format.

The request body contains deserialized JSON data of the complex “CourseModel”, as we mentioned before, each course has a tutor and related to subject, so sending the Ids for subject and tutor is enough because the “TheModelFactory.Parse” function is responsible to retrieve those objects from database and build valid domain object model which can be used with our repository.

If this POST request executed successfully at the server, and the a new course is created we’ll receive status code 201 (Resource Created) in response header along with the new course created on the server in response body. You can check the image blow:

Update existing Course using HTTP PUT action

We’ll add new method named Put(int Id, CourseModel courseModel) to “CoursesController”, as the implementation below:

Method named “PUT”, so the clients needs to issue HTTP PUT request, but we’ve added “HttpPatch” attribute to the Put method, so client can issue PUT or PATCH request and both will be executed using Put method. The difference between Put and Patch that if we want to update all fields of the “CourseModel” we need to use PUT, if we want to update partial fields we need to use PATCH, in our implementation we do not need to distinguish between those two actions.

Put method accepts two parameters, the Id of the updated resource which is set in URI, and the updated “CourseModel” which represents complex type deserialized in the request body.

We’ve returned proper “HttpResponseMessange” for all possible scenarios that might happen when we execute this operation. In case the resource is updated successfully, server should return HTTP response 200 (OK) along with the resource created. If the resource is not modified the server should return HTTP response 304 (Not modified).

To test this we need to use fiddler and choose the Composer tab, we’ll issue a PUT request to the URI: http://localhost:{your_port}/api/courses/33The request will look as the image below:

In this HTTP PUT request we need to note the following:

The “content-type” header is set to “application/json” because we are sending JSON data in request body.

The “accept” header is set to “application/json” because we are returning response in JSON format.

Method named “DELETE”, so the clients needs to issue HTTP DELETE request.

Delete method accepts the Id parameter of the deleted course, Id is set in URI, and the request body is empty.

We’ve returned proper “HttpResponseMessange” for all possible scenarios that might happen when we execute this operation. In case the resource is deleted successfully, server should return HTTP response 200 (OK). If the deletion of the resource failed server should return HTTP response 400 (Bad request) with explanation content why the request failed to process.

To test this we need to use fiddler and choose the Composer tab, we’ll issue a DELETE request to the URI: http://localhost:{your_port}/api/courses/33Notice that the body of the request is empty, the request will look as the image below:

Adding Students Controller to the Project

The new controller “StudentsController” will be responsible to do CRUD operations on Students. The controller will be responsible for executing the actions below:

List all available students by sending GET request to URI: http://localhost:{your_port}/api/students/

List single student by sending GET request to URI: http://{your_port}/api/students/HasanAhmad Note that we are identifying resource by passing userName not Id here. This method is secured using basic authentication, so resource owner only can query his detailed information once he provide userName and password. We’ll cover this in details once we talk about Securing Web API.

Add new student by sending POST request to URI: http://localhost:{your_port}/api/students/

I won’t list the code for “StudentsController” here as it is some how identical to “CoursesController”, you can browse it on GitHub. I will just list the new route configuration we’ve added to the “WebApiConfig” class.

1

2

3

4

5

config.Routes.MapHttpRoute(

name:"Students",

routeTemplate:"api/students/{userName}",

defaults:new{controller="students",userName=RouteParameter.Optional}

);

So in the next post we’ll cover how to implement Resources Association.

Hello Taiseer, First of all thank you for excellent tutorial on WebAPI. I was getting error message “This operation requires IIS integrated pipeline mode” in StudentController. Could you plz replace with correct code or explain why am i getting the error if i am wrong

What an excellent presentation. I’ve been researching this subject for a month now and have been compiling resources. To date yours is the most up-to-date and concise with the perfect amount of depth without being too verbose. I do have a question. Can your model factory be replaced with some sort of mapping framework like autoMapper or the like?

Glad you like this tutorial, and thanks for your compliment.
Absolutely you can use Auto Mapper instead of model factory pattern, I just prefer this one because it gives you the ability to manipulate your response before returning it.

Finally, I’m reaching your fifth part of Building ASP.Net Web API RESTful Service Series. I had to thank you more and more for your perfection.

But, unfortunately,
” A first chance exception of type ‘System.NullReferenceException’ occurred in portable.Web.dll
mobile :A first chance exception of type ‘System.ArgumentNullException’ occurred in EntityFramework.dll”, messages in my Immediate window during the debugging annoyed me for a long time when I’m trying to add item in my DB ( using Post ( ) ).
Today, I said: enough! and I decide to write you for advice because I don’t have much time to complete my school project.

i.e: When I test Get( ) and GetMobile( int id), it work without any exception and return me all informations what I need from my DB.

Thank you for everything,
Lots regard,

using portable.Data;
using portable.Data.Models;
using portable.Web.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

Hello Mohamed,
There is nothing wrong on your code, you were able to save the item in your database successfully or you are facing an exception?
The “First chance exception” is about debugger configuration, you can turn it of by un-checking the setting (Options->Debugging->General->Redirect all Output Window text to the Immediate Window in Tools).
Please read this post on stackoverflow to understand what is the first chance exception, this is something not related to Asp.Net Web API.
Hope this will help.

I started from Your advice ” There is nothing wrong on your code” and finally I found the problem.
In fact, I missed comma when I sent my request. ( I’m using advanced Rest client and I thought that it can understand without comma )
My request was like this :
{
nom: test
qauntite: 24
}
but I had to add comma to be like this :

You are welcome, I advice you to use Postman to issue your http requests and if you have complex JSON object always use JSON editor such as JSON editor online to validate your request payload. Good luck 🙂

Thanks for a fantastic tutorial – Much better details and closer to real life than most of the others I have seen. One question on this step though:

In the Post and Put methods you have a guard condition checking whether the parsed object is null:
if (entity == null)
Request.CreateErrorResponse(…);

Seems to me like it should be:
if (entity == null)
return Request.CreateErrorResponse(…);

Otherwise you will continue to process the rest of the function event though the entity object (or updatedCourse object in the case of the POST) is null, and you will never return the appropriate message with the BadRequest since what will actually be returned is the BadRequest created in the catch{}.

Great tutorial ! I am new to Web API. I thought it was supposed to be rather easy to flip back and forth between sending / receiving XML and JSON. I tried making a coupe changes in the program (as well as fiddler), but ran into errors. If it is an easy thing to do, can you provide any guidance ? Many thanks again for sharing this !

Hi Rob, Glad you liked it.
Web Api supports JSON and XML response by default, you need to set the preferred content type in Accept header.
As far as I remember i removed the XML response explicitly from my API, I need to support JSON only.
What is the error you faced?

Hi Thunder, well it is a REST design specification to include the ID of the updated resource in your request, but if you already have models that contain the ID, then you can update the resource without sending the Id in the URL.

Well, Which one is the best for developing REST?
Also, do you have any books that you recommend to read and learn REST design specifications?
By the way, thanks for these articles that certainly broadened my horizons.