MVC3 - 使用ViewModel插入 - 未将对象引用设置为对象的实例

时间:2011-11-05 13:31:23

标签: asp.net-mvc-3 entity-framework viewmodel

我有两个模型,如下所示,我试图从一个视图中插入一个模型到数据库。我创建了一个视图模型,试图这样做。

public class Blog
{
    public int BlogID { get; set; }
    public string Title { get; set; }
    public DateTime CreatedOn { get; set; }

    public virtual User User { get; set; }
    public virtual ICollection<BlogPost> Posts { get; set; }     
}

public class BlogPost
{
    public int PostID { get; set; }
    public string Body { get; set; }
    public DateTime CreatedOn { get; set; }

    public int UserID { get; set; }
    public virtual User User { get; set; }
}

public class BlogViewModel
{
    public Blog Blog { get; set; }
    public BlogPost BlogPost { get; set; }
}

使用视图模型我发布到创建控制器:

[HttpPost]
    public ActionResult Create(BlogViewModel blog)
    {
        if (ModelState.IsValid)
        {
            User user = unit.UserRepository.GetUser();
            blog.Blog.User = user;
            blog.Blog.CreatedOn = DateTime.Now;

            unit.BlogRepository.Insert(blog.Blog);
            unit.BlogPostRepository.Insert(blog.BlogPost);
            unit.Save();

            return RedirectToAction("Index");  
        }

        return View(blog);
    }

这不断抛出错误

  

对象引用未设置为对象的实例。

blog.Blog.User = user行。

对我做错了什么的想法?

修改 我检查了POST数据,它就在那里并且正确但它将所有内容都发布为Blog.Title =BlogPost.Body =,因此控制器中的viewmodel没有收到任何内容。如果我将控制器actionresult更改为:

public ActionResult Create(Blog blog, BlogPost post)

然后一切正常。那么为什么不以viewmodel格式发送数据呢?我正在使用基于显式视图模型的视图和控制器之间的交互

@model Test.Models.BlogViewModel
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Blog</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.Blog.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Blog.Title)
            @Html.ValidationMessageFor(model => model.Blog.Title)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.BlogPost.Body)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.BlogPost.Body)
            @Html.ValidationMessageFor(model => model.BlogPost.Body)
        </div>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

3 个答案:

答案 0 :(得分:35)

只需重命名您的操作参数:

public ActionResult Create(BlogViewModel viewModel)

存在冲突,因为您的操作参数称为blog,但您的视图模型(BlogViewModel)具有名为Blog的属性。问题是默认模型绑定器不再知道在这种情况下该做什么。

哦,如果您绝对需要将您的操作参数称为blog,那么您还可以在视图模型上重命名Blog属性。

答案 1 :(得分:4)

我之前遇到过这种情况。当您从视图发送的数据不是格式时,会发生这种情况,MVC默认模型绑定引擎可以理解或可以映射到您的视图模型对象。尝试使用“FireBug”并查看数据如何通过POST传递。然后看,如果该数据可以映射到您的视图模型的定义。

还有一件事,你是使用jQuery传递数据还是在视图和控制器之间使用基于显式视图模型的交互?

答案 2 :(得分:0)

@Michael Willmott

虽然这个主题已有6年历史,但我发现它对我最近处理过的场景非常有用。

在我的MVC视图中,改为使用标识符的完整路径,我使用带Razor的内联快捷方式变量,这导致回发视图模型到服务器为空。那是因为&#34;名称&#34;和&#34; id&#34; html元素的属性未正确呈现,因为MVC绑定机制需要:

以下是错误的声明:

@{
   var b = Model.Blog; // short cut caused problem of postback model binding
}

<div class="editor-field">
            @Html.EditorFor(model => b.Title)
            @Html.ValidationMessageFor(model => b.Title)
        </div>

以下是正确的声明,因为需要标识符的完整路径:

<div class="editor-field">
            @Html.EditorFor(model => model.Blog.Title)
            @Html.ValidationMessageFor(model => model.Blog.Title)
        </div>