GibboK
GibboK

Reputation: 73918

How to add a list to a View Model MVC

I'm using MVC 3 with View Model, in my case I have a View Model that should display a list of items and also a form for inserting some input.

I have problem in my View because I'm not able to associate the Form for inserting the data with the view model, could you tell me what I'm doing wrong?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using TestGuestBook.Models;

namespace TestGuestBook.ViewModel
{
    public class ListAddCommentsViewModel
    {
        public int CommentId { get; set; }

        [Required]
        public string Nominative { get; set; }

        [Email]
        public string Email { get; set; }

        [Required]
        public string Content { get; set; }

        public List<Comment> CommentItems { get; set; }
    }
}

View

@model IEnumerable<TestGuestBook.ViewModel.ListAddCommentsViewModel>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>ListAddCommentsViewModel</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.CommentId)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.CommentId)
            @Html.ValidationMessageFor(model => model.CommentId)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Nominative)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Nominative)
            @Html.ValidationMessageFor(model => model.Nominative)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Email)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Email)
            @Html.ValidationMessageFor(model => model.Email)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Content)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Content)
            @Html.ValidationMessageFor(model => model.Content)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            CommentId
        </th>
        <th>
            Nominative
        </th>
        <th>
            Email
        </th>
        <th>
            Content
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.CommentId)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Nominative)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Email)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Content)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
        </td>
    </tr>
}

</table>

Upvotes: 2

Views: 48348

Answers (2)

Latyn
Latyn

Reputation: 11

This is the best solution, I had checked almost all information and this is the one working!! Thanks

    public  ActionResult UploadFile(UploadFileViewModel model)
    {
        if (ModelState.IsValid)
        {
            var file = model.File;
            var parsedContentDisposition =
            ContentDispositionHeaderValue.Parse(file.ContentDisposition);
            var filename = Path.Combine(_environment.WebRootPath,
                "Uploads", parsedContentDisposition.FileName.Trim('"'));
            file.SaveAsAsync(filename);
        }

        return View();
    }

Upvotes: 0

Shyju
Shyju

Reputation: 218732

You dont need to pass a Collection to your View. Only one object of the ViewModel is enough. Your ViewModel already have property to holde the collection (List of Comments)

So in your GET Action, return only one instance of this viewModel to the View

public ActionResult GetComments(int postId)
{
  var viewModel=new ListAddCommentsViewModel();
  viewModel.CommentItems =db.GetComments(postId);
  return View(viewModel);
}

and now in your View, Let it bind to a single instance of ListAddCommentsViewModel

@model TestGuestBook.ViewModel.ListAddCommentsViewModel

And Inside your view, to Show your List of comments, use the Collection type property (Model.CommentItems) in your ViewModel

@foreach (var item in Model.CommentItems) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.CommentId)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Nominative)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Email)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Content)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new {  @id=item.PrimaryKey  }) |
            @Html.ActionLink("Details", "Details", new {  @id=item.PrimaryKey  }) |
            @Html.ActionLink("Delete", "Delete", new { @id=item.PrimaryKey  })
        </td>
    </tr>
}

Upvotes: 9

Related Questions