I am trying to add a record into my database using custom model binder
public class PostModelBinder: DefaultModelBinder
{
private IBlogRepository repository;
public PostModelBinder(IBlogRepository repo)
{
repository = repo;
}
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var post = (Post)base.BindModel(controllerContext, bindingContext);
if (post.Category != null)
post.Category = repository.Category(post.Category.CategoryID);
var tags = bindingContext.ValueProvider.GetValue("Tags").AttemptedValue.Split(',');
if (tags.Length > 0)
{
post.Tags = new List<Tag>();
foreach (var tag in tags)
{
post.Tags.Add(repository.Tag(int.Parse(tag.Trim())));
}
}
return post;
}
}
when I try to submit my record, I get Object reference not set to an instance of an object error on this line
post.Category = repository.Category(post.Category.CategoryID);
I am not sure why its causing this error.
Here is how I set up model binder in Global.asax.cs
//model binder
var repository = DependencyResolver.Current.GetService<IBlogRepository>();
ModelBinders.Binders.Add(typeof(Post), new PostModelBinder(repository));
My repository
public Category Category(int id)
{
return context.Categories.FirstOrDefault(c => c.CategoryID == id);
}
and my controller action
[HttpPost]
public ContentResult AddPost(Post post)
{
string json;
ModelState.Clear();
if (TryValidateModel(post))
{
var id = repository.AddPost(post);
json = JsonConvert.SerializeObject(new
{
id = id,
success = true,
message = "Post added successfully."
});
}
else
{
json = JsonConvert.SerializeObject(new
{
id = 0,
success = false,
message = "Failed to add the post."
});
}
return Content(json, "application/json");
}
and this is the factory i am using:
public class NinjectControllerFactory: DefaultControllerFactory
{
private IKernel ninjectKernel;
public NinjectControllerFactory()
{
ninjectKernel = new StandardKernel();
AddBindings();
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return controllerType == null
? null
: (IController)ninjectKernel.Get(controllerType);
}
private void AddBindings()
{
ninjectKernel.Bind<IBlogRepository>().To<EFBlogRepository>();
ninjectKernel.Bind<IAuthProvider>().To<FormsAuthProvider>();
}
}
I fixed the issue.
First of all, I switched ninject controller factory with ninject dependency resolver.
After using the dependency resolver, I get another error saying "An entity object cannot be referenced by multiple instances of IEntityChangeTracker" See Here
So I tried the suggested answer in that question and still no hope(but this also helped me in the end). I then asked another question in the comment section of this post part-5-creating-a-post, and realized there is a ninject mvc extension for dependency injection, I installed the extension, added my bindings in there and removed my own dependency resolver, with the help of previous answer, I added "InRequestScope()" (You have to have Ninject.Web.Common for this) and it worked.
So inside NinjectWebCommon.cs under App_Start folder:
kernel.Bind<IBlogRepository>().To<EFBlogRepository>().InRequestScope();