Почему моя ViewModel пуста на [HttpPost]? .NET MVC 3 - PullRequest
5 голосов
/ 22 октября 2011

Я стараюсь изо всех сил правильно использовать ViewModels в моем веб-приложении, но я сталкиваюсь с различными проблемами. Одним из них является то, что если я устанавливаю точку останова сразу после публикации с использованием действия Create, моя viewModel не сохранила ни одно из значений моей формы. Должно быть, я что-то делаю не так, но я попробовал несколько вещей. Включая приведенный ниже код, где я называю элементы формы такими же, как поля viewModel, чтобы посмотреть, поможет ли это.

Мне также интересно, какие именно свойства в вашей модели представления должны представлять. Я видел, как люди используют разные вещи в блогах и тому подобное.

Если представление будет отображать список выбора, у меня сложилось впечатление, что модель представления должна содержать IEnumerable SelectListItem для этого, как показано ниже. И все же я видел, как люди используют вместо этого IEnumerable Entity для представления типа, который представляет список выбора.

Кто-нибудь может пролить свет на это для меня? Вчера вечером я удалил всю свою бизнес-логику, чтобы начать все заново и попытаться сделать все правильно.

Моя ViewModel:

public class ServerCreateViewModel
{
    public int Id { get; set; }

    // CompanyName represents a field in the Company model. I did this to see if
    // it would help with model binding. Beforehand it was Companies to represent the type. I've done the same for the rest of them, so I wont comment on this again.
    public IEnumerable<SelectListItem> CompanyName { get; set; }

    // Represents the Game model.
    public IEnumerable<SelectListItem> GameTitle { get; set; }

    //Represents the Location model, etc...
    public IEnumerable<SelectListItem> City { get; set; }
    public IEnumerable<SelectListItem> NumberOfPlayers { get; set; }
    public IEnumerable<SelectListItem> CurrencyAbbreviation { get; set; }
}

Действие My Controller:

    public ActionResult Create()
    {
        var viewModel = new ServerCreateViewModel();

        viewModel.CompanyName = new SelectList(_dataService.Companies.All(), "Id", "CompanyName");
        viewModel.GameTitle = new SelectList(_dataService.Games.All(), "Id", "GameTitle");
        viewModel.City = new SelectList(_dataService.Locations.All(), "Id", "City");
        viewModel.NumberOfPlayers = new SelectList(_dataService.ServerPlayers.All(), "Id", "NumberOfPlayers");

        return View(viewModel);
    } 

    [HttpPost]
    public ActionResult Create(FormCollection collection, ServerCreateViewModel viewModel)
    {
        try
        {      // I put a breakpoint in here to check the viewModel values.
               // If I dont pass the viewModel into the constructor, it doesnt exist.
               // When I do pass it in, its empty.
            return Content("Success");
        }
        catch
        {
            return Content("Fail");
        }
    }  

My View:

@model GameserverCompare.ViewModels.Server.ServerCreateViewModel


@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<fieldset>
    <legend>Server</legend>
    @Html.HiddenFor(m => m.Id)
     <div class="editor-label">
        @Html.LabelFor(model => model.CompanyName)
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(m => Model.CompanyName, Model.CompanyName)
        @Html.ValidationMessageFor(model => model.CompanyName)
    </div>
     <div class="editor-label">
        @Html.LabelFor(model => model.GameTitle)
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(m => Model.GameTitle, Model.GameTitle)
        @Html.ValidationMessageFor(model => model.GameTitle)
    </div>
    <div class="editor-label">
        @Html.LabelFor(model => model.City)
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(m => Model.City, Model.City)
        @Html.ValidationMessageFor(model => model.City)
    </div>
    <div class="editor-label">
        @Html.LabelFor(model => model.NumberOfPlayers)
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(m => Model.NumberOfPlayers, Model.NumberOfPlayers)
        @Html.ValidationMessageFor(model => model.NumberOfPlayers)
    </div>
    <p>
        <input type="submit" value="Create" />
    </p>

</fieldset>
}   

1 Ответ

4 голосов
/ 22 октября 2011

Поскольку вы используете свойства SelectList в модели формы, вам понадобится другая модель для представления выбранных значений в этих списках:

public class ServerCreatePostbackModel
{
    public int Id { get; set; }

    // CompanyName represents a field in the Company model. 
    public string CompanyName { get; set; }

    // Represents the Game model.
    public string GameTitle { get; set; }

    //Represents the Location model, etc...
    public string City { get; set; }
    public int NumberOfPlayers { get; set; }
    public string CurrencyAbbreviation { get; set; }
}

Пусть ваше действие HttpPost примет одно из них какего аргумент.

О, и обязательно используйте HiddenFor для свойства Id, чтобы он возвращался с другими данными.

...