Почему данные не передаются в моей ViewModel? - PullRequest
1 голос
/ 28 ноября 2010

Эй, я работаю в службе поддержки в MVC2, и у меня возникла проблема с тем, что данные не передаются из моих представлений через мои ViewModels.

На главной странице у меня есть три DropDownLists, из которых вы можете выбрать проблемную область. Затем вы можете нажать кнопку, чтобы сообщить о проблеме или перейти к часто задаваемым вопросам. Если вы выбрали проблемную область в DropDownLists, сайт должен запомнить, что вы выбрали, передав данные с помощью viewmodel.

Но когда я добираюсь до метода Post для домашнего индекса, мои SelectLists и SelectListItems равны нулю, тогда как строка для хранения информации о кнопке содержит правильные данные.

Что я делаю не так?

Это мой домашний контроллер:

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)
    {
        // snip
    }

Моя модель представления:

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; }
}

И мой домашний индекс (который унаследован от HomeIndexViewModel, я просто не включил код, потому что он испортил сообщение):

<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>
<%} %>

Спасибо за ваше время. : -)

Ответы [ 3 ]

3 голосов
/ 28 ноября 2010

Когда вы отправляете форму обратно в действие POST, совершенно нормально, что свойства problemAreas1,2,3 будут иметь значение null, поскольку их содержимое никогда не публикуется. Вам нужно будет заселить их так же, как в действии GET. Что касается свойств itemOne, Two, Three, то они должны быть простыми строковыми значениями, а не типа SelectListItem.

Модель:

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; }
}

Контроллер:

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");
}
0 голосов
/ 28 ноября 2010

Ваши списки выбора будут нулевыми, потому что эти данные не передаются обратно в форму, что должно быть в порядке. Однако, поскольку они имеют значение null, SelectListItem MVC не может найти в коллекции для возврата, поэтому он также является нулевым.

Попробуйте добавить следующее к вашему конструктору HomeIndexViewModel вместо контроллера (просто чтобы посмотреть, что происходит)

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

То, что, как я полагаю, произойдет с возвращаемым POST, механизм связывания создаст вашу HomeIndexViewModel с заполненными списками SelectList и должен иметь возможность заполнить ваш SelectListItem.

Что-то кажется немного подозрительным. Мой внутренний инстинкт подсказывает мне, что SelectListItem не должен быть нулевым.

0 голосов
/ 28 ноября 2010

Я не вижу в вашем представлении директивы страницы, что бы она знала о вашей модели?

Примерно так должно быть в первой строке вашего представления:

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