【问题标题】:Object reference not set to an instance of an object when using custom model binding使用自定义模型绑定时未将对象引用设置为对象的实例
【发布时间】:2014-08-14 09:26:26
【问题描述】:

我正在尝试使用自定义模型绑定器将记录添加到我的数据库中

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;
    }
}

当我尝试提交我的记录时,我得到 Object reference not set to an instance of an object error on this line

post.Category = repository.Category(post.Category.CategoryID);

我不确定它为什么会导致这个错误。

这是我在 Global.asax.cs 中设置模型绑定器的方法

//model binder
var repository = DependencyResolver.Current.GetService<IBlogRepository>();
ModelBinders.Binders.Add(typeof(Post), new PostModelBinder(repository));

我的仓库

public Category Category(int id)
{
    return context.Categories.FirstOrDefault(c => c.CategoryID == id);
}

和我的控制器操作

[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");
}

这是我正在使用的工厂:

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>();
    }
}

【问题讨论】:

  • @nvoigt 谢谢,我明白了那个帖子。Category 给了我 null 值,但我不明白为什么它给我 null
  • 也发布您的观点,我也不确定您如何使用提交按钮提交数据?阿贾克斯?等等,也许您需要在视图@Html.HiddenFieldFor(m =&gt; m.Category.CategoryID) 中创建隐藏字段,我只是在信息有限的情况下在这里猜测
  • @Yuliam 我的视图是 jqgrid,所以没有任何自定义代码,只有一个链接到我的控制器的 url

标签: c# asp.net-mvc entity-framework ninject custom-model-binder


【解决方案1】:

我解决了这个问题。

首先,我用 ninject 依赖解析器切换了 ninject 控制器工厂。

使用依赖解析器后,我收到另一个错误消息“IEntityChangeTracker 的多个实例无法引用实体对象”See Here

所以我尝试了该问题中建议的答案,但仍然没有希望(但这最终也帮助了我)。然后我在这篇文章part-5-creating-a-post 的评论部分提出了另一个问题,并意识到有一个用于依赖注入的 ninject mvc 扩展,我安装了该扩展,在其中添加了我的绑定并删除了我自己的依赖解析器,在之前的帮助下回答,我添加了“InRequestScope()”(为此,您必须拥有 Ninject.Web.Common)并且它有效。

所以在 App_Start 文件夹下的 NinjectWebCommon.cs 里面:

kernel.Bind<IBlogRepository>().To<EFBlogRepository>().InRequestScope();

【讨论】:

    【解决方案2】:

    这是一个模型绑定问题。 Category 对象未正确绑定 POST 值。使用 Firebug 或其他工具查看 CategoryID 是否是从 jqGrid 发布的。

    【讨论】:

    • 网格确实在发布 CategoryID,我已经使用 WORKING 解决方案检查了我的 POSTed 值,两者完全相同。编码的唯一区别是我使用的是实体框架而不是 NHibernate,而且我的自定义模型绑定器不同,我认为问题出在我的自定义模型绑定器中,但我不知道它是什么
    猜你喜欢
    • 2021-04-28
    • 2011-05-18
    • 1970-01-01
    • 2020-03-05
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多