Andy Xufuris
Andy Xufuris

Reputation: 708

Problems Passing ViewModel with data from View to Controller

Ok, here is my problem. I am trying to pass a view model of mine, which has multiple list in it, to my view. Then in my view i need to edit the different list. Then on my post i need to save the edits. Although, when i pass my viewmodel back to my post, it is empty! Can somebody explain what i am doing wrong? i am not worried about saving the information right now, i am just worried about getting the data back to the controller. The ViewModel is null when i hit that portion.

Controller

    public ActionResult ManageNewsArticles()
    {
        NewsViewModel newsViewModel = new NewsViewModel();

        newsViewModel.ListBreakingNews = db.NewsArticles.Where(n => n.PageSetupID == 1).ToList<NewsArticle>();
        newsViewModel.ListMainArticle = db.NewsArticles.Where(n => n.PageSetupID == 2).ToList<NewsArticle>();
        newsViewModel.ListSubNews1 = db.NewsArticles.Where(n => n.PageSetupID == 3).ToList<NewsArticle>();
        newsViewModel.ListSubNews2 = db.NewsArticles.Where(n => n.PageSetupID == 4).ToList<NewsArticle>();
        newsViewModel.ListSubNews3 = db.NewsArticles.Where(n => n.PageSetupID == 5).ToList<NewsArticle>();

        return View(newsViewModel);
    }

    [HttpPost]
    public ActionResult ManageNewsArticles(NewsViewModel newsViewModel)
    {
        if (ModelState.IsValid)
        {
            db.SaveChanges();
            return RedirectToAction("Admin");
        }

        return View(newsViewModel);
    }

here is my View

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<TrueNews.ViewModels.NewsViewModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
 Manage News Articles
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Manage News Articles</h2>

    <% Html.EnableClientValidation(); %>

    <% using (Html.BeginForm(Model)) {%>
        <%: Html.ValidationSummary(true) %>

        <fieldset>
            <%: Html.EditorForModel(Model) %>
            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>

    <% } %>

    <div>
        <%: Html.ActionLink("Back to Admin Controls", "Admin") %>
    </div>
</asp:Content>

NewsViewModel

public class NewsViewModel
    {
        public List<NewsArticle> ListBreakingNews { get; set; }
        public List<NewsArticle> ListMainArticle { get; set; }
        public List<NewsArticle> ListSubNews1 { get; set; }
        public List<NewsArticle> ListSubNews2 { get; set; }
        public List<NewsArticle> ListSubNews3 { get; set; }
    } // End of Class

Upvotes: 1

Views: 4417

Answers (1)

JayneT
JayneT

Reputation: 765

I couldn't get your view to display correctly using the EditorForModel syntax, however I did replicate your problem and found this article which provides one way of solving it:

http://weblogs.asp.net/nmarun/archive/2010/03/13/asp-net-mvc-2-model-binding-for-a-collection.aspx

I created a quick table NewsArticle containing Id and Stuff columns and then had the following form in the view:

<% using (Html.BeginForm())
   {%>
<%: Html.ValidationSummary(true) %>
<fieldset>

    <% for (int i = 0; i < Model.ListBreakingNews.Count; i++)
       { %>
    <div>
        Id</div>
    <div>
        <%= Html.TextBox(string.Format("ListBreakingNews[{0}].Id", i), Model.ListBreakingNews[i].Id) %>
    </div>
    <div>
        Name</div>
    <div>
        <%= Html.TextBox(string.Format("ListBreakingNews[{0}].Stuff", i), Model.ListBreakingNews[i].Stuff) %>
    </div>
    <% } %>
    <p>
        <input type="submit" value="Save" />
    </p>
</fieldset>
<% } %>

and the items in the list were passed when posted. I also found that previously you had Html.BeginForm(Model) which when I added it caused nothing to be passed through in the view model - I am only a newbie to MVC so I don't know why this happens but my code below worked only with Html.BeginForm() and not Html.BeginForm(Model).

I hope this helps.

Upvotes: 2

Related Questions