I am trying to follow the suggested best practices using ViewModels.
In my forum application, I want to publish a list of messages, and add a text box at the bottom of the screen so that the answers can be published.
I think I need a ViewModel for the Posts list, and a ViewModel for the response will be published (TopicId and Content).
Therefore, it seems to me that I need to combine these two ViewModels together in the third ViewModel, and in my view, iterate over the Posts ViewModel and then below, create a form where I have part of the ViewModel response - and Postback sends only the ReplyViewModel controller to controller.
My view models:
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 and then create an empty ReplyViewModel and then merge them into 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 opinion, I:
@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 can I refer to two separate ViewModels in PostListAndReplyVM sent to the view. eg. if I think it should be something like:
@Html.DisplayFor(modelItem => itemitem.PostViewModel.PostId)
... but this gives an error:
'centreforum.Models.PostListAndReplyVM' does not contain a definition for "PostId" and no extension method "PostId" that takes the first argument of the type "centreforum.Models.PostListAndReplyVM" can be found
And for the part of the list:
@foreach (var item in Model.PostViewModel)
... gives an error:
"System.Collections.Generic.IEnumerable" does not contain a definition for "PostViewModel" and does not use the extension method "PostViewModel" that takes the first argument of the type "System.Collections.Generic.IEnumerable" that can be found
I am sure that I am missing something simple - thanks for any help,
Mark