1

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>();
    }
}
Mindless
  • 2,352
  • 3
  • 27
  • 51
  • possible duplicate of [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – nvoigt Aug 11 '14 at 06:14
  • @nvoigt Thanks, I get that post.Category is giving me null value, but what I don't understand is why it is giving me null – Mindless Aug 11 '14 at 06:39
  • post your view too, also I'm not sure how you submit the data, using submit button? ajax? etc.., perhaps you need to create hidden field in the view `@Html.HiddenFieldFor(m => m.Category.CategoryID)`, I'm just guessing here with limited information – Yuliam Chandra Aug 11 '14 at 06:59
  • @Yuliam my view is a jqgrid, so there isn't any custom code, just a url linking to my controller – Mindless Aug 11 '14 at 08:16

2 Answers2

2

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();
Community
  • 1
  • 1
Mindless
  • 2,352
  • 3
  • 27
  • 51
1

This is a model binding issue. The Category object is not properly binded with the POSTed values. Use Firebug or some tool and see whether the CategoryID is POSTed from jqGrid.

VJAI
  • 32,167
  • 23
  • 102
  • 164
  • The grid is indeed posting the CategoryID, I've checked my POSTed value with a WORKING solution, both are exactly the same. The only difference in coding is i am using entity framework instead of NHibernate, and my custom model binder is different, I think the problem is in my custom model binder, but I don't know what it is – Mindless Aug 12 '14 at 10:10