In the previous post we have highlighted the flaws in current implementation of Courses controller, in this post we’ll be fixing those flaws.

Configuring Formatters

Web API provides media-type formatters for both JSON and XML. The framework inserts these formatters into the pipeline by default. Clients can request either JSON or XML in the Accept header of the HTTP request. In order to configure the JSON formatter we need to implement the code below in class “WebApiConfig”:

What we did here that we looked at the built in formatters of type JSON, then we changed the contract resolver of the serialization settings to use Camel Case resolver. Now all JSON objects properties return in camel case.

Implement Dependency Injection using Ninject

If Dependency Injection concept is new to you, I recommend to read my previous post about it.

Now to prepare our code for dependency injection we need to add new Base API controller class named “BaseApiController” to folder “Controllers”. This class will derive from “APIController” class and its constructor accepts the Repository Interface “ILearningRepository” as parameter, we’re planing to implement DI ConstructorInjection Pattern. The code will look as below:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

publicclassBaseApiController:ApiController

{

privateILearningRepository _repo;

publicBaseApiController(ILearningRepository repo)

{

_repo=repo;

}

protectedILearningRepositoryTheRepository

{

get

{

return_repo;

}

}

}

Now our “CoursesController” will derive from the “BaseApiController”, we need to use now Ninject as DI framework to do the heavy lifting for us and resolve the dependencies between our components, to install Ninject use NuGet package Manager and install the following packages:

Ninject

Ninject.Web.Common

WebApiContrib.IoC.Ninject

Update (2014-04-21) Thanks to Thando Toto and Francesco to point out the issue related for no generating the file “NinjectWebCommon” by default, this is due some changes done on Ninject packages used here, so in order to follow along with dependency injection part we need to install the same assemblies with the right version used in this tutorial, so open NuGet Package Manager Console (View -> Other Windows -> Package Manager Console) and install the following packages along the right version used in this tutorial:

Install-Package Ninject -Version 3.0.1.10

Install-Package Ninject.Web.Common -Version 3.0.0.7

Install-Package WebApiContrib.IoC.Ninject -Version 0.9.3

After we install those package successfully a new file named “NinjectWebCommon” is added to the App_Start folder, this file is responsible of the heavy lifting to configure the dependencies in our project, now we need to specify the dependencies between our components. As you remember in this post, when we created the “LearningRepository” its constructor accepts the database context object “LearningContext” so the “LearningRepository” class depends on the database context to work, we need register this in Ninject Kernel.

So to configure Web API to use DI we need to add the following code to the class “NinjectWebCommon”:

As you notice we are configuring Ninject to have a single instance of database context object shared by all objects created via the kernel for that HTTP request. This is good technique for sharing objects that are expensive to create. you can read more about Ninject Object Scopes here.

Implement the Model Factory Pattern

The Model Factory Pattern will help us in shaping and controlling the response returned to the client, so what we will do here is to create a simplified model for each domain object model (entity) we have in the database. i.e. “Course” entity will map to “CourseModel”, “Tutor” entity will map to “TutorModel” taking in consideration the relations between models (Each course is taught by a Tutor and related to a Subject) etc…

To implement this we need to add new folder named “Models” and add four classes named “SubjectModel”, “TutorModel”, “CourseModel”, and “EnrollmentModel”. Those are only simple POCO classes which will be used to return the data to the client, the code for classes will be as below:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

publicclassSubjectModel

{

publicintId{get;set;}

publicstringName{get;set;}

}

publicclassTutorModel

{

publicintId{get;set;}

publicstringEmail{get;set;}

publicstringUserName{get;set;}

publicstringFirstName{get;set;}

publicstringLastName{get;set;}

publicData.Enums.Gender Gender{get;set;}

}

publicclassCourseModel

{

publicintId{get;set;}

publicstringUrl{get;set;}

publicstringName{get;set;}

publicdoubleDuration{get;set;}

publicstringDescription{get;set;}

publicTutorModelTutor{get;set;}

publicSubjectModelSubject{get;set;}

}

publicclassEnrollmentModel

{

publicDateTimeEnrollmentDate{get;set;}

publicCourseModelCourse{get;set;}

}

Now we need to use those classes to create the response for the client, we need a single class which is responsible for creating those models, so we’ll add a class named “ModelFactory” as the code below:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

publicclassModelFactory

{

publicModelFactory()

{

}

publicCourseModel Create(Course course)

{

returnnewCourseModel()

{

Id=course.Id,

Name=course.Name,

Duration=course.Duration,

Description=course.Description,

Tutor=Create(course.CourseTutor),

Subject=Create(course.CourseSubject)

};

}

publicTutorModel Create(Tutor tutor)

{

returnnewTutorModel()

{

Id=tutor.Id,

Email=tutor.Email,

UserName=tutor.UserName,

FirstName=tutor.FirstName,

LastName=tutor.LastName,

Gender=tutor.Gender

};

}

publicSubjectModel Create(Subject subject)

{

returnnewSubjectModel()

{

Id=subject.Id,

Name=subject.Name

};

}

publicEnrollmentModel Create(Enrollment enrollment)

{

returnnewEnrollmentModel()

{

EnrollmentDate=enrollment.EnrollmentDate,

Course=Create(enrollment.Course)

};

}

}

What we’ve done above is simple, we’ve overloaded the function named “Create”, so it accepts domain object input i.e. “Course” and returns a new model of type “CourseModel”. Notice how we can control the object graph and the chaining of objects and sub-objects i.e (CourseModel -> TutorModel, and CourseModel -> SubjectModel).

By doing this we’ve fixed two important flaws we have identified in the previous post which they are:

Self referencing when returning chain ob objects.

Controlling the fields returned to the client. (i.e. “TutorModel” is not returning the “password” fields in the response).

Using the Model Factory in “CoursesController” and coming controllers we’ll talk about is fairly simple, thanks for the “BaseApiController” where all controllers will derive from it. Open “BaseApiController” and add the code below:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

publicclassBaseApiController:ApiController

{

privateModelFactory _modelFactory;

protectedModelFactoryTheModelFactory

{

get

{

if(_modelFactory==null)

{

_modelFactory=newModelFactory();

}

return_modelFactory;

}

}

}

What we done here is adding read only property which is responsible to create an instance of the model factory class.

Before introducing changes to the “CoursesController” we need to fix the last two flaws in the previous implementation which they are:

Link each resource returned to a URI.

Returning HTTP status codes when returning single resource.

Fix the flaw in Linking each resource returned to a URI:

Returning URI for each resource is simple, thanks to the Model Factory pattern we implemented, so for example if we want to add URI to identify Course resource we need to do the following:

Pass an instance of “HttpRequestMessage” to the “ModelFactory” constructor in order to create object of type “System.Web.Http.Routing.UrlHelper” which is responsible to formulate the URI link for this resource based on the “Route Name” we configured in class “WebApiConfig”.

Add new property named “URL” to the “CourseModel” which will contain the URI for this resource.

Code listing as the below respecting points sequence:

1

2

3

4

5

6

7

8

9

publicclassModelFactory

{

privateSystem.Web.Http.Routing.UrlHelper _UrlHelper;

publicModelFactory(HttpRequestMessage request)

{

_UrlHelper=newSystem.Web.Http.Routing.UrlHelper(request);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

publicclassBaseApiController:ApiController

{

privateModelFactory _modelFactory;

protectedModelFactoryTheModelFactory

{

get

{

if(_modelFactory==null)

{

_modelFactory=newModelFactory(Request);

}

return_modelFactory;

}

}

}

1

2

3

4

5

6

7

8

9

10

11

12

publicclassModelFactory

{

publicCourseModel Create(Course course)

{

returnnewCourseModel()

{

Url=_UrlHelper.Link("Courses",new{id=course.Id}),

Id=course.Id,

/*Other CourseModel properties remain the same*/

};

}

}

There is a nice plural sight learning course produced by Shawn Wildermuth which discuss deeply this Model Factory Pattern. I recommend watching this course.

Fix the flaw in returning HTTP status codes when returning single resource

Web API framework contains class named “HttpResponseMessage” which can be used to return HTTP status code and data if needed, it is a good practice to return “HttpResponseMessage” objects because it gives us the flexibility to set response code and actual content, you will notice in the code below that we’ll be returning object of type “HttpResponseMessage” for action GetCourse(int id) instead of returning the actual Course domain object.

In the code listing below we’ll implement all the fixes we’ve discussed:

Using the model factory to create “CourseModel” and sub models “TutorModel” and “SubjectModel”.

Returning HTTP status codes for action GetCourse(int id), so if the course was not found we’ll return 404, in case of an exception we’ll return 400 (Bad request) along with the exception message, and if the course is found we’ll return 200 (OK) along with a serialized representation of “CourseModel” object found.

To test the new changes let’s issue a GET request the URI http://localhost:{your_port}/api/courses, and notice how each resource returned has a URL property, as well we have shaped the response returned and controlled the object graph to overcome circular reference serialization issue.

You can do this for sure, but I’m following REST architecture specification called HATEOAS which stands for “Hypermedia as the Engine of Application State”. In simple words each resource returned in the response can be accessed by the clients through simple fixed URL, that’s why Im returning a fixed URL in the body insted of adding it to the header, you can read more about this here: http://en.wikipedia.org/wiki/HATEOAS

In case you haven’t got a chance to look into the issue I mentioned above, I think sharing what I figured out may be helpful for someone trying to learn and debug your code.

GlobalConfiguration contains a default filter provider (ActionDescriptorFilterProvider) out of box. By adding another custom IFilterProvider, you end up with having two sets of filter execution mechanism. That’s why the OnAuthorization method of every filter in the pipeline gets called twice. Simply removing the default one would solve the problem.

I appreciate your detailed clarification and solution of the issue, to be honest I didn’t notice that OnAuthorization method get called twice, I’ll debug the issue and apply what you suggested. Thanks again for your update.

Questsion: On installing Ninject and the dependencies you’ve listed, nothing worked until I added another dependency “Ninject,MVC4”. Did I perhaps miss something or did you neglect to mention this dependency in you tutorial?

I’ve just tried it again and had the same problem. The NinjectWebCommon class file only gets created if Install Ninject.MVC4. Still not sure what I’m doing wrong but I thought it’s worth mentioning in case another reader goes through the same issue.

That’s the first thing I tried to do actually but it seemed like I still needed something from the actual assembly so it didn’t work. Will give it another this way and let you know what exactly was missing.

Hello Thando, I’ve updated the part where we install the Ninject Nuget packages by including the right version numbers used in this tutorial, this should generate the file “NinjectWebCommon” by default. Seems there are changes on newer Nuget packages prevents from generating the file until you install Ninject.MVC4 package.

Great Tutorial, but… unfortunately I have to confirm problem related to injection.

NinjectWebCommon.cs is generated only by adding Ninject.MVC4. But this is not enough, ninject assembly versions are newer than what is used inside the sample and this seems to make the difference. I had to fix here and there:
– changing System.Web.Http and System.Web.Http.WebHost from 5.0.0 (not supported) to 4.0.0
– fixing WebAPiConfig.cs and Global.asax.cs
– ecc…

Thanks for your feedback, I’ve updated the part where we install the Ninject Nuget packages by including the right version numbers used in this tutorial, this should generate the file “NinjectWebCommon” by default. Seems there are changes on newer Nuget packages prevents from generating the file until you install Ninject.MVC4 package.

HI, if you use WebApi 2 then you can also use the latest versions of Ninject but you need to add also this package “Ninject Web Host for WebApi 2” to generate the file “NinjectWebCommon”. Taken from SO: http://stackoverflow.com/a/24842387

If you do not stick to the file “NinjectWebCommon” and use OWIN then you can follow this SO http://stackoverflow.com/a/24195811 . I followed it and it worked for me.
BTW, thank you for your great tutorial.

these package in the given order then the common file “NinjectWebCommon” is added to automatically created App_Start folder in Learning.Data (Data layer) not in Learning.Web as in your code. I think i will be problem with projects properties can you help me to solve it.

You’ve installed the NuGet package on the wrong project (Learning.Data). You have to install them on the Web Project (Learning.Web), once you open NuGet package manager console, notice there is drop down list on the top of the window which allows you to specify which project you want to install packages on, choose project “Learning.Web” to follow up with the tutorial. Do not forget to remove the NuGet package from the “Learning.Data” project. Hope this will solve your issue.

Hello Mr taiseer
i have problem when i get api/courses without BaseApicontroller every thing work will but api/courses/id dont work because of Self referencing loop detected for property ‘Course’ with type ‘Learning.Data.Entities.Course’. Path ‘Enrollments[0] but when i fixed it and rewrite the code and refrence BaseApi Controller an error Accures says Learning.Web.Controllers.CoursesController’ does not have a default constructor i did the previous steps one by one i dont know what is happining so please did you face this error befor i cant solve it i have trying for 3 days

Hi Ayesh,
The idea of using the “BaseApiController” is to faciliate having singleton object of the ModelFactory class which will be used to solve the self referencing issues, make sure you are implementing the method “public CourseModel Create(Course course)” correctly in you ModelFactory class. There is another ways to solve the self referencing issues one way you can follow here but I do not recommend it.

Hi,
I believe this issue is happening when yo open the project in VS2013, I build this tutorial on VS2012, so you need only to change the access modifiers for all constructors to Public.
Let me know if this works.

Thank you for making such a helpful and complete tutorial!
I’m getting the same “parameterless constructor” error. I’m using VS2013, and made sure the constructors are all public, but still get the error. Francesco’s solution bypassing injection works, but I’d like to make it work with injection.

[solved] I figured out what happened. When I installed the Ninject packages (v3.2.0) NinjectWebCommon was not created. I reinstalled the packages a couple of times, but it was still not created. I created it as an empty class, and then added your code from this lesson. I saw that your version of the file had more methods, but I thought they would be manually added in a later lesson in this series. After reading a bunch of articles about using Ninject, I noticed that it automatically generates the Start() and Stop() methods, and also the two WebActivator (WebActivatorEx in my case) calls to ensure that those methods are fired. Since I added those to NinjectWebCommon.cs everything is working fine. Onward!

How to implement the CourseController to include the Enrollments?
I see Course GetCourse(int courseId, bool includeEnrollments = true); in ILearningRepository, but didn’t see the code in to handle includeEnrollments in CoursesController. Can you help?

Great tutorial. Very clear and concise. However, I am stuck on something. After this post, I have implemented Ninject and DI. When I load http://localhost:%5Bmy port]/api/courses I get the following error in the model factory when in the Create .

A route named ‘Courses’ could not be found in the route collection.\r\nParameter name: name

I have a question regarding the ninject service registration, in my project I made sure not to expose the interface implementation (in your case LearningRepository),Is there is a way I can bind the interface with the implementation using ninject without exposing it to the web api project?

Hi Amjad,
The short answer no, with the current implementation the concrete implementation (LearningRespository) for the interface (ILearningRespository) resides in the same assembly and you need both to be available on the WebAPi project in order to bind the services in method RegisterServices in NinjectWebCommon class and implement the IoC.

This has been for a while, I’m sure you are using different version from Ninject other than the one I used in the post, so it is hard to troubleshoot the issue, my recommendation is to fall back to the same version I used in the post or you keep Googling until you find a solution. Apologies for not having time to troubleshoot this issue.

1. Based on this, i need to create a ModelFactory for all my view parsing? is this the best practice
2. If i follow one parser for each module, I cant create as baseapi. so here what is the best practice

Thanks. I will check. Now i have a confusion. I am updating navigation property while parse to business entity from ViewModel. This is needed to return the data including navigation property after add the record.

But i am having separate controller, business login and repository for each functionality and how i mingle to get the object of navigation property from another controller?

Trackbacks

[…] use a lot of separate classes for API/view models in my ASP.NET work (using the highly recommended model factory pattern, with the factory being AutoMapper :), and I’ve at least once ended up with a single static […]