Reputation: 7818
I'm trying to follow suggested best practice, by using ViewModels.
In my forum app, I want to post a list of posts, and at the bottom of the screen, add a textbox so replies can be posted.
So in my mind, I need a ViewModel for the Posts list, and a ViewModel for the Reply to be posted (TopicId and Content).
Therefore, I think I need to combine these two ViewModels together in a third ViewModel, and in my View, iterate over the Posts part of the ViewModel, and then at the bottom, create a form, where I have the Reply part of the ViewModel - and the Postback sends just the ReplyViewModel to the controller.
My ViewModels are:
public class PostViewModel
{
public int PostId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Author { get; set; }
public DateTime DateOfTopic { get; set; }
}
public class ReplyViewModel
{
public int TopicId { get; set; }
public string Content { get; set; }
}
public class PostListAndReplyVM
{
public List<PostViewModel> PostViewModel { get; set; }
public ReplyViewModel ReplyViewModel { get; set; }
}
In my controller I populate the PostViewModel, then create an empty ReplyViewModel, then combine them in a PostListAndReplyVM:
//
// GET: /Post/List/5
public ActionResult List(int id = 0)
{
// Populate PostViewModel
var post = db.Posts.Include(x => x.Topic)
.Select(p => new PostViewModel
{
PostId = p.TopicId,
Title = p.Title,
Description = p.Content,
DateOfTopic = p.DateOfPost,
Author = p.Author
}
).ToList();
// Populate empty ReplyViewModel
ReplyViewModel prvm = new ReplyViewModel();
prvm.Content = "";
prvm.TopicId = id;
// Combine two viewmodels into a third, to send to the controller
PostListAndReplyVM pvm = new PostListAndReplyVM();
pvm.ReplyViewModel = prvm;
pvm.PostViewModel = post;
// Return combined ViewModel to the view
return View(pvm);
}
Then in my view I have:
@model IEnumerable<centreforum.Models.PostListAndReplyVM>
<table class="table table-condensed table-striped table-hover table-bordered">
<tr>
<th>
@Html.DisplayNameFor(model => model.PostId)
</th>
....
....
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.PostId)
</td>
How do I refer to the two separate ViewModels within the PostListAndReplyVM posted to the view. eg. if I think it should be something like:
@Html.DisplayFor(modelItem => itemitem.PostViewModel.PostId)
...but that gives the error:
'centreforum.Models.PostListAndReplyVM' does not contain a definition for 'PostId' and no extension method 'PostId' accepting a first argument of type 'centreforum.Models.PostListAndReplyVM' could be found
And for the list part:
@foreach (var item in Model.PostViewModel)
...gives an error of:
'System.Collections.Generic.IEnumerable' does not contain a definition for 'PostViewModel' and no extension method 'PostViewModel' accepting a first argument of type 'System.Collections.Generic.IEnumerable' could be found
I'm sure I'm missing something simple - thanks for any help,
Mark
Upvotes: 4
Views: 4485
Reputation: 6499
I think you made an error on your view, you return a PostListAndReplyVM on your controller and your view reference an IEnumerable of PostListAndReplyVM.
You have to change the declarated model in your view
@model centreforum.Models.PostListAndReplyVM
Hope it's help
Upvotes: 3