This is the fourth part of Building ASP.Net Web API RESTful Service Series. The topics we’ll cover are:
- Building the Database Model using Entity Framework Code First – Part 1.
- Applying the Repository Pattern for the Data Access Layer – Part 2.
- Getting started with ASP.Net Web API – Part 3.
- Implement Model Factory, Dependency Injection and Configuring Formatters – Part 4 (This Post).
- Implement HTTP actions POST, PUT, and DELETE In Web API – Part 5.
- Implement Resources Association – Part 6.
- Implement Resources Pagination – Part 7.
- Securing Web API – Part 8.
- Preparing Web API for Versioning – Part 9.
- Different techniques to Implement Versioning – Part 10.
- Caching resources using CacheCow and ETag – Part 11.
Update (2014-March-5) Two new posts which cover ASP.Net Web API 2 new features:
Implement Model Factory, Dependency Injection and Configuring Formatters
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”:
1 2 3 4 5 6 7 8 9 |
public static class WebApiConfig { public static void Register(HttpConfiguration config) { var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First(); jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); } } |
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 Constructor Injection Pattern. The code will look as below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class BaseApiController : ApiController { private ILearningRepository _repo; public BaseApiController(ILearningRepository repo) { _repo = repo; } protected ILearningRepository TheRepository { 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:
NinjectNinject.Web.CommonWebApiContrib.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”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public static class NinjectWebCommon { private static IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel); kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); //Suport WebAPI Injection GlobalConfiguration.Configuration.DependencyResolver = new WebApiContrib.IoC.Ninject.NinjectResolver(kernel); RegisterServices(kernel); return kernel; } private static void RegisterServices(IKernel kernel) { kernel.Bind<LearningContext>().To<LearningContext>().InRequestScope(); kernel.Bind<ILearningRepository>().To<LearningRepository>().InRequestScope(); } } |
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 |
public class SubjectModel { public int Id { get; set; } public string Name { get; set; } } public class TutorModel { public int Id { get; set; } public string Email { get; set; } public string UserName { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public Data.Enums.Gender Gender { get; set; } } public class CourseModel { public int Id { get; set; } public string Url { get; set; } public string Name { get; set; } public double Duration { get; set; } public string Description { get; set; } public TutorModel Tutor { get; set; } public SubjectModel Subject { get; set; } } public class EnrollmentModel { public DateTime EnrollmentDate { get; set; } public CourseModel Course { 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 |
public class ModelFactory { public ModelFactory() { } public CourseModel Create(Course course) { return new CourseModel() { Id = course.Id, Name = course.Name, Duration = course.Duration, Description = course.Description, Tutor = Create(course.CourseTutor), Subject = Create(course.CourseSubject) }; } public TutorModel Create(Tutor tutor) { return new TutorModel() { Id = tutor.Id, Email = tutor.Email, UserName = tutor.UserName, FirstName = tutor.FirstName, LastName = tutor.LastName, Gender = tutor.Gender }; } public SubjectModel Create(Subject subject) { return new SubjectModel() { Id = subject.Id, Name = subject.Name }; } public EnrollmentModel Create(Enrollment enrollment) { return new EnrollmentModel() { 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 |
public class BaseApiController : ApiController { private ModelFactory _modelFactory; protected ModelFactory TheModelFactory { get { if (_modelFactory == null) { _modelFactory = new ModelFactory(); } 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”.
- Pass “Request” object of type “System.Net.Http.HttpRequestMessage” in class “BaseApiController” to “ModelFactory” constructor.
- 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 |
public class ModelFactory { private System.Web.Http.Routing.UrlHelper _UrlHelper; public ModelFactory(HttpRequestMessage request) { _UrlHelper = new System.Web.Http.Routing.UrlHelper(request); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class BaseApiController : ApiController { private ModelFactory _modelFactory; protected ModelFactory TheModelFactory { get { if (_modelFactory == null) { _modelFactory = new ModelFactory(Request); } return _modelFactory; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 |
public class ModelFactory { public CourseModel Create(Course course) { return new CourseModel() { 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:
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 |
public class CoursesController : BaseApiController { public CoursesController(ILearningRepository repo) : base(repo) { } public IEnumerable<CourseModel> Get() { IQueryable<Course> query; query = TheRepository.GetAllCourses(); var results = query .ToList() .Select(s => TheModelFactory.Create(s)); return results; } public HttpResponseMessage GetCourse(int id) { try { var course = TheRepository.GetCourse(id); if (course != null) { return Request.CreateResponse(HttpStatusCode.OK, TheModelFactory.Create(course)); } else { return Request.CreateResponse(HttpStatusCode.NotFound); } } catch (Exception ex) { return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex); } } } |
- We’ve introduced multiple changes to “CoursesController” which they are:
- Injected the “ILearningRepository” inside “CoursesController” constructor.
- 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.
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 |
[{ "id": 1, "url": "http://localhost:8323/api/courses/1", "name": "History Teaching Methods 1", "duration": 5, "description": "The course will talk in depth about: History Teaching Methods 1", "tutor": { "id": 1, "email": "Ahmad.Joudeh@outlook.com", "userName": "AhmadJoudeh", "firstName": "Ahmad", "lastName": "Joudeh", "gender": 0 }, "subject": { "id": 1, "name": "History" } }, { "id": 2, "url": "http://localhost:8323/api/courses/2", "name": "History Teaching Methods 2", "duration": 4, "description": "The course will talk in depth about: History Teaching Methods 2", "tutor": { "id": 1, "email": "Ahmad.Joudeh@outlook.com", "userName": "AhmadJoudeh", "firstName": "Ahmad", "lastName": "Joudeh", "gender": 0 }, "subject": { "id": 1, "name": "History" } }] |
So in the next post we’ll cover how to implement the HTTP verbs (POST,PUT, and DELETE).
Hello Taiseer,
Not sure if you’ve noticed there’s an issue with the following statement in your code:
//Support injection in WebAPI filters
GlobalConfiguration.Configuration.Services.Add(typeof(IFilterProvider), new NinjectWebApiFilterProvider(kernel));
This will result in the OnAuthorization method of every filter in the pipeline getting called twice. Any idea?
Thanks
In the CoursesController GetCourse method, instead of just
return Request.CreateResponse(HttpStatusCode.OK, TheModelFactory.Create(course));
why not do this
var response = Request.CreateResponse(HttpStatusCode.OK,TheModelFactory.Create(course));
response.Headers.Location = /* AND BUILD THE URL TO RETURN HERE? */
This way you don’t have to add the Url field to CourseModel or pass the HttpRequestMessage object to the ModelFactory.
Hello Scott,
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
@Taiseer,
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.
//remove the default ActionDescriptorFilterProvider
var providers = GlobalConfiguration.Services.GetFilterProviders();
var defaultprovider = providers.First(p => p is ActionDescriptorFilterProvider);
GlobalConfiguration.Services.Remove(typeof(IFilterProvider), defaultprovider);
//add a custom filter provider to support DI in filters
GlobalConfiguration.Services.Add(typeof(IFilterProvider), new NinjectWebApiFilterProvider(kernel));
Hello abedon,
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.
Hi
Thanks for a great tutorial. THis is exactly what I needed.
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?
Thando
Hello Thando,
Glad you like it!
That is strange if you forked the original source code you will notice that there is no dependency on “Ninject.MVC4.dll” I’m using just Ninject.dll and Ninject.Web.Common.dll. assemblies.
Thanks for the response.
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.
Thanks again for the turorial.
T
Can you try to add the file “NinjectWebCommon” file manually without installing Ninject.MVC4?
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.
Just noticed the update. Thanks Taiseer.
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…
But more I fix, more troubles follows…
Just a note to confirm that without Injection it works fine.
To avoid Injection, I’ve recreated Learning.Web project and skipped all injections steps (Nuget and code).
On BaseApiController I’ve implemented TheRepository as follows:
protected ILearningRepository TheRepository
{
get
{
if (_repo == null)
{
_repo = new LearningRepository(new LearningContext());
}
return _repo;
}
}
…and constructor for CoursesController class:
public CoursesController() : base()
{}
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
Thank you, I’ll check this too.
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.
Hi Taiseer this is really a great post.I tried to install the
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
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.
Hello,
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,
I am new here.
Agree that we need to point out which project we will add Package. My command like below:
Install-Package Ninject -Version 3.0.1.10 -ProjectName Learning.Web
Install-Package Ninject.Web.Common -Version 3.0.0.7 -ProjectName Learning.Web
Install-Package WebApiContrib.IoC.Ninject -Version 0.9.3 -ProjectName Learning.Web
Also, I need to add package dependency in web.config too:
@Taiseer: any idea?
Thank you so much much for your great Blog.
Trung.
Hi, you have added the packages correctly, but I do not get what is the issue you are facing now. Web.config should be updated automatically once you install the packages.
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.
Hello,
I have gone wrong somewhere but unsure where, I receive
Make sure that the controller has a parameterless public constructor
:s
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.
Hi Rodman, I’ll check this issue again on freshly installed vs 2013, strange why it is not showing on vs 2012 thanks for your feedback!
[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!
Super! Thank you for sharing this, I’ll update the post with your solution to stay up to date.
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?
Hi Taiseer,
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 am not sure why this is being loaded. Any ideas?
thanks,
Andy
Nevermind …. checking the WebApiConfig, I forgot to rename the route from Default to Courses…..
Hi Andy, no problem, glad to hear that tutorial was useful 🙂
Hi taiseer,
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.
Hello there, many thanks for this tutorial.. it’s really help me a lot to learn .NET technology.
but right now i have a problem, when i implement ninject,
i have this error,
An error has occurred.
Type ‘Learning.Web.Controllers.CoursesController’ does not have a default constructor
System.ArgumentException
at System.Linq.Expressions.Expression.New(Type type) at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
i already follow step by step, but in this step i got this error..
sorry for my bad English..
Hi, glad it was helpful.
That has been for a while, but I guess it is related to Ninject, make sure you are using the same version in the tutorial.
Hi there!
I had the same problem ‘Learning.Web.Controllers.CoursesController’ does not have a default constructor’
Apparently it is a known error with Ninject and you can find the solution on
http://stackoverflow.com/questions/17462175/mvc-4-web-api-controller-does-not-have-a-default-constructor
I implemented the proposed solution and the problem was fixed!
regards
Bart
Thanks Bart for sharing, I’m sure it will be helpful for someone facing the same issue.
I downloaded the project, and there was this StudentBaseModel with a column URL. What is the use of it?
also can you explain about StudentModel and StudentBaseModel ? Why are there these two different models for Student?
Hi, when you proceed with this tutorial and you reach versioning section you will understand the differences.
Till this step, i have an issue,
An exception of type ‘System.EntryPointNotFoundException’ occurred in System.Web.Http.dll but was not handled in user code
Additional information: Entry point was not found.
I googled it, and it say something problem with the web.config and ninject stuff. but I replaced my web config with yours from github, it still return error.
the exception launced @ global.asax at this line : GlobalConfiguration.Configure(WebApiConfig.Register);
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.
actually this is my second time try to build this. But my first time stuck on this step as well. I added the version that you strikedout as well but the result still the same . I installed :
Ninject -Version 3.0.1.10
Ninject.Web.Common -Version 3.0.0.7
WebApiContrib.IoC.Ninject -Version 0.9.3
and by you mean, you are using these version ?
Ninject
Ninject.Web.Common
WebApiContrib.IoC.Ninject
404 error . can’t access my localhost .. when I checked my view folder nothing there is empty .
great articles. Here i have 2 confusions in ModelFactory
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
I recommend using AutmoMapper not doing it by hand.
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?
Automapper handle this case also?
I am asking about this method;
public Course Parse(CourseModel model)
{
try
{
var course = new Course()
{
Name = model.Name,
Description = model.Description,
Duration = model.Duration,
CourseSubject = _repo.GetSubject(model.Subject.Id),
CourseTutor = _repo.GetTutor(model.Tutor.Id)
};
return course;
}
catch (Exception)
{
return null;
}
}
Here CourseSubject is updated by getting the record from database. In this example it is single repo. But in may case all are independent
I’d like to find out more? I’d like to find out more details.