0

プレーヤーを含むドロップダウンリストを持つ作成ページがあります

これをコントローラーに入力します

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

これにより、ビューが正常に読み込まれます

@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 を SelectedListItem にキャストして、新しい 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);
}
4

1 に答える 1

1

元の回答: 問題は、CreatePlayerList() メソッドで ID を文字列にキャストしているため、MVC がモデルの ID (GUID) に基づいて選択された項目を取得できないことです。Player1ID と Player2ID は、データベースで何をするかに関係なく、ViewModel では文字列である必要があります。

コメントから得た実際の回答: エラー メッセージのテキストにもかかわらず、問題は Player1ID が IEnumerable または IEnumerable である必要があることではなく、リストがモデルから削除されているか、リストに ID が含まれていないことです。ModelState が有効でない場合は、ViewModel を調べて、無効なものとその理由を判断する必要があります。ModelState.Remove() を使用して、モデルの欠陥を再構築する必要がある場合があります。

于 2013-05-07T18:49:41.977 に答える