在服务器端使用MVC 4验证失败的情况下,重新选择DropDownListFor上的选定项目

本文关键字:选择 DropDownListFor 项目 新选择 MVC 服务器端 验证 情况下 失败 | 更新日期: 2023-09-27 18:12:35

我有一个创建页面,有一个下拉列表的球员

我将其填充到控制器

[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 populate 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" />    
}

然后在Post上,我做了一些验证,其中ModelState无效,所以下面运行

[HttpPost]
public ActionResult Create(CreateMatchViewModel vm)
{
    try
    {
        if (!ModelState.IsValid)
        {
            vm.PlayerList = CreatePlayerList();
            vm.Winner = CreateWinnerList();
            return View(vm);
        }

但这失败了以下错误,但我不知道如何将Guid转换为selectedlisttitem,以便在新的Get请求上再次选择列表中的相同项目

键'Player1ID'的ViewData项的类型是'System '。Guid',但必须是'IEnumerable'类型。

视图模型

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

编辑这使它工作

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

在服务器端使用MVC 4验证失败的情况下,重新选择DropDownListFor上的选定项目

原答案:问题是,在您的CreatePlayerList()方法中,您正在将id转换为字符串,因此MVC无法根据模型中的id获得所选项目,这是一个guid。Player1ID和Player2ID需要在你的ViewModel中是字符串,不管你在你的数据库中对它们做什么。

从评论中找到的实际答案:问题,尽管错误消息的文本不是Player1ID需要IEnumerable或IEnumerable,但列表从模型中消失,或者列表不包含ID。当ModelState无效时,您(可能)需要检查ViewModel,并确定无效的内容及其原因。您可能必须使用ModelState.Remove()来重建模型中的错误。