ASP.NET提交表单时Enigma的Game属性无法填充求助
问题描述
作为ASP.NET新手,在添加Enigma(谜题)时需要关联雷顿教授系列的对应游戏,为此制作了对应数据库游戏的下拉选择框,但提交表单时,Enigma的必填Game字段未被填充,导致验证失败。
视图代码
@model ProfessorLayton.Models.Enigma @{ ViewData["Title"] = "Create"; } <h2>Add an enigma to the current list of enigmas</h2> <hr /> <div class="row"> <div class="col-md-4"> <form asp-action="Create"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="Name" class="control-label"></label> <input asp-for="Name" class="form-control" /> <span asp-validation-for="Name" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Content" class="control-label"></label> <input asp-for="Content" class="form-control" /> <span asp-validation-for="Content" class="text-danger"></span> </div> <br> Chose the game in which this enigma is in : <div class="form-group"> <select asp-for="GameId" class="form-control" asp-items="ViewBag.GameId"></select> <span asp-validation-for="GameId" class="text-danger"></span> </div> <br> <div class="form-group"> <input type="submit" value="Ajouter l'énigme" class="btn btn-primary" /> </div> </form> </div> </div> @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} }
控制器代码
//GET: enigma/Create public async Task<IActionResult> Create() { var enigma = await _context.Enigmas .Include(g=>g.Game) .Include(s=>s.Solution) .ToListAsync(); var availableGamesQuery=from g in _context.Games select g; var availableGames=availableGamesQuery.ToList(); ViewData["Enigma"]=enigma; ViewData["GameId"]=new SelectList(availableGames,"Id","Title") ; return View(); } //Méthode d'action pour l'ajout d'une enigme [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([Bind("Id,Name,Content,GameId")] Enigma enigma,List<Game> games) { // Apply model validation rules if (ModelState.IsValid) { _context.Add(enigma); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } else { // At this point, something failed: redisplay form // var allErrors = ModelState.Values.SelectMany(v => v.Errors.Select(b => b.ErrorMessage)); // return Json(new {allErrors}); return View(enigma); } }
问题分析与解决方案
核心问题
- POST方法验证失败返回视图时,未重新填充
ViewBag.GameId的下拉选项,导致下拉框为空,用户无法重新选择游戏,进而触发Game字段必填验证错误 - POST方法参数中的
List<Game> games无实际作用,属于冗余参数 - 视图顶部未使用的
Game game = (Game)ViewData["Game"]!;可能引发空引用异常
修复步骤
1. 修复POST方法,重新填充下拉选项
当ModelState验证失败时,必须重新加载游戏列表并赋值给ViewBag.GameId,确保回传页面后下拉框有选项可选择:
[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([Bind("Id,Name,Content,GameId")] Enigma enigma) { if (ModelState.IsValid) { _context.Add(enigma); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } // 验证失败时重新填充下拉选项 var availableGames = await _context.Games.ToListAsync(); ViewData["GameId"] = new SelectList(availableGames, "Id", "Title"); return View(enigma); }
2. 移除冗余代码
- 删除POST方法参数中的
List<Game> games - 删除视图顶部的
Game game = (Game)ViewData["Game"]!;
3. 优化GET方法(可选)
GET方法中获取所有Enigma的代码无意义,可简化:
//GET: enigma/Create public async Task<IActionResult> Create() { var availableGames = await _context.Games.ToListAsync(); ViewData["GameId"] = new SelectList(availableGames, "Id", "Title"); return View(); }
4. 确保模型验证配置正确
确认Enigma模型中GameId字段标记了必填验证:
public class Enigma { public int Id { get; set; } [Required] public string Name { get; set; } [Required] public string Content { get; set; } [Required(ErrorMessage = "请选择游戏")] public int GameId { get; set; } public Game Game { get; set; } // 其他属性... }
内容的提问来源于stack exchange,提问作者Klaph
相关产品推荐
相关产品推荐

