ASP.NET Core 3.1点击Save按钮报错:找不到Save视图求助
问题分析
错误InvalidOperationException: 未找到视图'Save'的核心原因是:你的Save动作方法执行完后调用了return View(model);,ASP.NET Core会默认寻找与动作方法同名的视图(即Save.cshtml),但你的项目中仅存在Index.cshtml,因此找不到对应视图。
解决方案
可根据需求选择以下任意一种方案:
方案1:返回Index视图
若希望保存后仍回到Index页面并展示模型数据,修改Save方法的返回语句,明确指定返回Index视图:
[HttpPost] [ActionName("Save")] [ValidateAntiForgeryToken] public IActionResult Save(CascadingModel model) { if (ModelState.IsValid) { var newstaffrecords = new StaffDetailVM() { StaffId = model.StaffId, StaffName = model.StaffName, CountryName = model.CountryName, StateName = model.StateName, CityName = model.CityName, }; this.Context.Stafftbl.Add(newstaffrecords); this.Context.SaveChanges(); // 可选:添加保存成功提示 TempData["SuccessMsg"] = "数据保存成功"; } else { // 模型验证失败时,重新加载下拉列表数据,避免下拉框为空 model.Countries = (from customer in this.Context.Countries select new SelectListItem { Value = customer.CountryId.ToString(), Text = customer.CountryName }).ToList(); // 保留已选的州和城市数据 if(model.CountryId > 0) { model.States = (from customer in this.Context.States where customer.CountryId == model.CountryId select new SelectListItem { Value = customer.StateId.ToString(), Text = customer.StateName }).ToList(); if(model.StateId > 0) { model.Cities = (from customer in this.Context.Cities where customer.StateId == model.StateId select new SelectListItem { Value = customer.CityId.ToString(), Text = customer.CityName }).ToList(); } } } return View("Index", model); // 明确指定返回Index视图 }
方案2:重定向到Index动作(推荐PRG模式)
遵循Post/Redirect/Get模式,保存成功后重定向到Index,避免重复提交问题:
[HttpPost] [ActionName("Save")] [ValidateAntiForgeryToken] public IActionResult Save(CascadingModel model) { if (ModelState.IsValid) { var newstaffrecords = new StaffDetailVM() { StaffId = model.StaffId, StaffName = model.StaffName, CountryName = model.CountryName, StateName = model.StateName, CityName = model.CityName, }; this.Context.Stafftbl.Add(newstaffrecords); this.Context.SaveChanges(); TempData["SuccessMsg"] = "数据保存成功"; return RedirectToAction("Index"); // 重定向到Index动作 } // 验证失败时,返回原视图并重新加载下拉数据 model.Countries = (from customer in this.Context.Countries select new SelectListItem { Value = customer.CountryId.ToString(), Text = customer.CountryName }).ToList(); if(model.CountryId > 0) { model.States = (from customer in this.Context.States where customer.CountryId == model.CountryId select new SelectListItem { Value = customer.StateId.ToString(), Text = customer.StateName }).ToList(); if(model.StateId > 0) { model.Cities = (from customer in this.Context.Cities where customer.StateId == model.StateId select new SelectListItem { Value = customer.CityId.ToString(), Text = customer.CityName }).ToList(); } } return View("Index", model); }
在Index.cshtml中添加提示显示代码:
@if(TempData["SuccessMsg"] != null) { <div class="alert alert-success">@TempData["SuccessMsg"]</div> }
方案3:创建Save视图
若需要单独的保存结果页面,在/Views/Home/目录下创建Save.cshtml视图,根据需求编写页面内容(如保存成功/失败提示)。
额外修正点
你的视图中下拉框手动设置的name属性会覆盖asp-for的绑定逻辑,导致模型绑定失败,需删除手动添加的name属性:
<!-- 修正后的国家下拉框 --> <select id="ddlCountries" asp-for="CountryId" asp-items="Model.Countries" class="form-control"> <option value="">--请选择--</option> </select> <!-- 州和城市下拉框同理,删除name属性 --> <select id="ddlStates" asp-for="StateId" asp-items="Model.States" class="form-control"> <option value="">--请选择--</option> </select> <select id="ddlCities" asp-for="CityId" asp-items="Model.Cities" class="form-control"> <option value="">--请选择--</option> </select>
修正后才能正确绑定CountryId、StateId、CityId字段,同时需确保CascadingModel中的CountryName、StateName、CityName能通过对应ID从数据库查询赋值。
内容的提问来源于stack exchange,提问作者dausa
相关产品推荐
相关产品推荐

