Mark
Mark

Reputation: 7818

ASP.Net MVC C# two viewmodels within another viewmodel - how to reference in the view

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

Answers (1)

Joffrey Kern
Joffrey Kern

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

Related Questions