开发者

Why isn't data transfered in my ViewModel?

Hey, I'm working on a helpdesk in MVC2, and I'm having a problem with data not being transferred from my views through my ViewModels.

On the home page, I have three DropDownLists where you can choose a problem area from. You can then push a button to either report a problem or go to the FAQ. If you choose a problem area in the DropDownLists, the site should remember what you chose by having the data transfer with the viewmodel.

But when I get to the Post method for home Index, my SelectLists and SelectListItems are null, whereas the string for containing the button info contains the correct data.

What am I doing wrong?

This is my home controller:

public ActionResult Index()
    {
        var viewModel = new HomeIndexViewModel()
        {
            // The lists with problem areas are populated.
            problemAreas1 = new SelectList(helpDeskRepos开发者_Python百科itory.GetProblemAreas(), "ProblemAreaID", "ProblemAreaName"),
            problemAreas2 = new SelectList(helpDeskRepository.GetProblemAreas(), "ProblemAreaID", "ProblemAreaName"),
            problemAreas3 = new SelectList(helpDeskRepository.GetProblemAreas(), "ProblemAreaID", "ProblemAreaName")
        };
        return View(viewModel);
    }

    //
    // POST: /Home/

    [HttpPost]
    public ActionResult Index(HomeIndexViewModel viewModel)
    {
        // snip
    }

My viewmodel:

public class HomeIndexViewModel
{
    // A SelectList containing elements for the DropDownLists in the Home "Index" view.
    public SelectList problemAreas1 { get; set; }
    public SelectList problemAreas2 { get; set; }
    public SelectList problemAreas3 { get; set; }

    // Items chosen in the DropDownLists.
    public SelectListItem itemOne { get; set; }
    public SelectListItem itemTwo { get; set; }
    public SelectListItem itemThree { get; set; }

    // String for IDing what button is pressed.
    public string submitButton { get; set; }
}

And my home index view (which inherits from HomeIndexViewModel, I just didn't include the code because it screws up the post):

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm("Index", "Home", FormMethod.Post))
   {%>
<h2>
    Search for your problem:</h2>
<asp:Label ID="Label1" runat="server" Width="300px">
Choose a problem area, and search for an answer to your problem in the FAQ, 
    or you can press the report button to report your problem.</asp:Label>
<%-- Here are the DropDownLists. --%>
<p style="width: 220px; height: 24px;">
    <%: Html.DropDownListFor(model => Model.itemOne, Model.problemAreas1, "Choose a problem area")%>
</p>
<p style="width: 220px;">
    <%: Html.DropDownListFor(model => Model.itemTwo, Model.problemAreas2, "Choose a problem area")%>
</p>
<p style="width: 220px">
    <%: Html.DropDownListFor(model => Model.itemThree, Model.problemAreas3, "Choose a problem area")%>
</p>
<p>
    <%-- Here are the two buttons allowing people to do a search or create a new ticket respectively. --%>
    <input type="submit" value="Search for problems" name="submitButton" id="searchButton" />
    <input type="submit" value="Report problem" name="submitButton" id="submitButton" />
</p>
<%} %>

Thank you for your time. :-)


When you submit your form back to the POST action it is perfectly normal that the problemAreas1,2,3 properties will be null because their contents is never posted. You will need to repopulate them the same way you did in your GET action. As far as the itemOne,Two,Three properties are concerned they should be simple string values and not of type SelectListItem.

Model:

public class HomeIndexViewModel
{
    // A SelectList containing elements for the DropDownLists in the Home "Index" view.
    public SelectList problemAreas1 { get; set; }
    public SelectList problemAreas2 { get; set; }
    public SelectList problemAreas3 { get; set; }

    // Items chosen in the DropDownLists.
    public string itemOne { get; set; }
    public string itemTwo { get; set; }
    public string itemThree { get; set; }

    // String for IDing what button is pressed.
    public string submitButton { get; set; }
}

Controller:

public ActionResult Index()
{
    var viewModel = new HomeIndexViewModel()
    {
        // The lists with problem areas are populated.
        problemAreas1 = new SelectList(helpDeskRepository.GetProblemAreas(), "ProblemAreaID", "ProblemAreaName"),
        problemAreas2 = new SelectList(helpDeskRepository.GetProblemAreas(), "ProblemAreaID", "ProblemAreaName"),
        problemAreas3 = new SelectList(helpDeskRepository.GetProblemAreas(), "ProblemAreaID", "ProblemAreaName")
    };
    return View(viewModel);
}

//
// POST: /Home/

[HttpPost]
public ActionResult Index(HomeIndexViewModel viewModel)
{
    if (!ModelState.IsValid)
    {
        // the model wasn't valid =>
        // show the same form so that the user can fix validation errors
        viewModel.problemAreas1 = new SelectList(helpDeskRepository.GetProblemAreas(), "ProblemAreaID", "ProblemAreaName");
        viewModel.problemAreas2 = new SelectList(helpDeskRepository.GetProblemAreas(), "ProblemAreaID", "ProblemAreaName");
        viewModel.problemAreas3 = new SelectList(helpDeskRepository.GetProblemAreas(), "ProblemAreaID", "ProblemAreaName");
        return View(viewModel);
    }
    // TODO: everything went fine => update your database and redirect
    return RedirectToAction("Index");
}


I don't see the page directive on your view that let's it know about your model?

Something like this should be the first line of your view:

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


Your select lists will be null because that data is not passed back in the form, which should be ok. However, because they are null there is no SelectListItem MVC can find in the collection to return, so it is also null.

Try adding the following to your constructor of HomeIndexViewModel instead of in the controller (just to see what happens)

problemAreas1 = new SelectList(helpDeskRepository.GetProblemAreas(), "ProblemAreaID", "ProblemAreaName"), 
problemAreas2 = new SelectList(helpDeskRepository.GetProblemAreas(), "ProblemAreaID", "ProblemAreaName"), 
problemAreas3 = new SelectList(helpDeskRepository.GetProblemAreas(), "ProblemAreaID", "ProblemAreaName") 

What I believe will happen on the return POST the binder will create your HomeIndexViewModel with the SelectLists populated and should be able to populate your SelectListItem.

Something seems a bit fishy though. My gut instinct is telling me that the SelectListItem shouldn't be null though.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜