I have got two models, seen below, and am trying to insert one of each to the database from one view. I have created a view model in an attempt to do this.
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; }
}
Using the view model i am posting to the create controller:
[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);
}
This keep throwing the error
Object reference not set to an instance of an object.
on the line blog.Blog.User = user.
Any thoughts on what i’m doing wrong?
EDIT
I checked the POST data and it was all there and correct but it was posting everything as Blog.Title = and BlogPost.Body = so the viewmodel in the controller wasn’t receiving anything. If i change the controller actionresult to:
public ActionResult Create(Blog blog, BlogPost post)
Then it all works. So why doesn’t data sent in the viewmodel format? I am using explicit view model based interaction between your views and controller
@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>
Simply rename your action argument:
There is a conflict because your action argument is called
blogand yet your view model (BlogViewModel) has a property calledBlog. The problem is that the default model binder no longer knows what to do in such situation.Oh and if you absolutely need to have your action argument called
blogthen you could also rename theBlogproperty on your view model.