Reputation: 3647
I have a Create page that have a Dropdownlist with Players
This I populate in my controller
[HttpGet]
public ActionResult Create()
{
var vm = new CreateMatchViewModel
{
Winner =
CreateWinnerList(),
PlayerList = CreatePlayerList()
}
;
return View(vm);
}
private IEnumerable<SelectListItem> CreatePlayerList()
{
List<Player> playerList = _playerManagementRepository.GetAllPlayers();
return playerList.Select(p => new SelectListItem
{
Text = p.Username,
Value = p.Id.ToString()
});
}
private SelectListItem[] CreateWinnerList()
{
return new[]
{
new SelectListItem {Text = "Player 1", Value = 1.ToString(), Selected = true}
, new SelectListItem {Text = "Player 2", Value = 2.ToString(), Selected = false}
};
}
This populates my view fine
@model TableTennis.ViewModels.CreateMatchViewModel
@{
ViewBag.Title = "Enter Match Result";
}
@using (Html.BeginForm("Create", "Match", FormMethod.Post))
{
<h4>Player 1</h4>
@Html.DropDownListFor(p => p.Player1ID, Model.PlayerList)
<h4>Player 2</h4>
@Html.DropDownListFor(p => p.Player2ID, Model.PlayerList)
<h4>Winner</h4>
@Html.DropDownListFor(w => w.WinnerID, Model.Winner)
<h5>Set 1</h5>
@Html.EditorFor(p => p.Score1Set1)
@Html.EditorFor(p => p.Score2Set1)
<h5>Set 2</h5>
@Html.EditorFor(p => p.Score1Set2)
@Html.EditorFor(p => p.Score2Set2)
<h5>Set 3</h5>
@Html.EditorFor(p => p.Score1Set3)
@Html.EditorFor(p => p.Score2Set3)
<input type="submit" value="Add result" />
}
Then on Post I do some validation where ModelState is not valid, so the following is run
[HttpPost]
public ActionResult Create(CreateMatchViewModel vm)
{
try
{
if (!ModelState.IsValid)
{
vm.PlayerList = CreatePlayerList();
vm.Winner = CreateWinnerList();
return View(vm);
}
But this fails follwing error, but I am not sure how to cast the Guid to a SelectedListItem so that the same item in the list is selected again on the new Get request
The ViewData item that has the key 'Player1ID' is of type 'System.Guid' but must be of type 'IEnumerable'.
ViewModel
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace TableTennis.ViewModels
{
public class CreateMatchViewModel
{
public CreateMatchViewModel()
{
Score1Set1 = 0;
Score1Set2 = 0;
Score1Set3 = 0;
Score2Set1 = 0;
Score2Set2 = 0;
Score2Set3 = 0;
}
public IEnumerable<SelectListItem> PlayerList { get; set; }
public IEnumerable<SelectListItem> Winner { get; set; }
[Required]
public Guid Player1ID { get; set; }
[Required]
public Guid Player2ID { get; set; }
[Required]
public int WinnerID { get; set; }
[Required]
[RegularExpression("[0-9][0-9]?")]
public int Score1Set1 { get; set; }
[RegularExpression("[0-9][0-9]?")]
[Required]
public int Score1Set2 { get; set; }
[RegularExpression("[0-9][0-9]?")]
[Required]
public int Score1Set3 { get; set; }
[RegularExpression("[0-9][0-9]?")]
[Required]
public int Score2Set1 { get; set; }
[RegularExpression("[0-9][0-9]?")]
[Required]
public int Score2Set2 { get; set; }
[RegularExpression("[0-9][0-9]?")]
[Required]
public int Score2Set3 { get; set; }
}
}
EDIT This made it work
if (!ModelState.IsValid)
{
ModelState.Clear();
vm.PlayerList = CreatePlayerList();
vm.Winner = CreateWinnerList();
return View(vm);
}
if (vm.Player1ID == vm.Player2ID)
{
ModelState.Clear();
vm.PlayerList = CreatePlayerList();
vm.Winner = CreateWinnerList();
return View(vm);
}
Upvotes: 0
Views: 280
Reputation: 907
Original answer: Problem is that in your CreatePlayerList() method you are casting the id to a string so MVC is unable to get the selected item based on the id in your model, which is a guid. Player1ID and Player2ID need to be strings in your ViewModel, no matter what you do with them in your database.
Actual answer, fished out of the comments: The problem, despite the text of the error message is NOT that Player1ID needs to be IEnumerable or IEnumerable but that the list is gone from the model, or the list does not contain the ID. You (may) need to examine the ViewModel when ModelState is not valid and determine what is not valid and why. You may have to use ModelState.Remove() along with reconstructing what is faulty in your Model.
Upvotes: 1