我正在创建一个新的 .NET Core MVC 项目,供人们用来提交在会议上演示的提案。
对于提案提交表单,我使用绑定模型(又名 ViewModel)来绑定表单上的用户输入。
这是绑定模型类的部分代码:
public class BaseSubmissionBindingModel
{
public BaseSubmissionBindingModel()
{
}
[Required]
public int ConferenceId { get; set; }
[Required]
[StringLength(250)]
[Display(Name = "Title")]
public string SubmissionTitle { get; set; }
[Required]
[StringLength(1000)]
[Display(Name = "Abstract")]
public string SubmissionAbstract { get; set; }
public IEnumerable<SelectListItem> SubmissionCategoryItems { get; set; }
[Required]
[Display(Name = "Select the Submission Category ")]
public string SelectedSubmissionCategory { get; set; }
}
注意字段
SubmissionCategoryItems
- 该字段用于填充视图中的下拉选择表单控件。该控件的数据来自数据库查询,显示哪些提交类别取决于会议 ID 值。
在 Controller 类中,我获取会议 ID 的提交类别,并为每个提交类别创建一个带有
List<SelectListItem> submissionCategoryItems
对象的 SelectListItem
。
然后创建
baseSubmissionBindingModel
对象并将 submissionCategoryItems
分配给 IEnumerable<SelectListItem> SubmissionCategoryItems
。
控制器然后返回
View(baseSubmissionBindingModel)
。
用户输入的视图页面正确呈现,并且“选择提交类别”选择框具有每个提交类别的正确选项。
以下是创建提交表单上的 HTML:
<div class="form-group">
<label asp-for="SelectedSubmissionCategory"></label>
<select asp-for="SelectedSubmissionCategory" asp-items="@Model.SubmissionCategoryItems">
<option value="" selected> --select-- </option>
</select>
<span asp-validation-for="SelectedSubmissionCategory"></span>
</div>
如果用户未在表单上输入所需值,然后单击表单的提交按钮,则会出现我的问题。
我的控制器类具有下面的
CreateSubmission
方法,当用户单击表单上的“提交”时会调用该方法:
public IActionResult CreateSubmission(BaseSubmissionBindingModel baseSubmissionBindingModel)
{
if (!ModelState.IsValid)
{
return View("Index", baseSubmissionBindingModel);
}
Log.Information("Submission data provided is " + baseSubmissionBindingModel.ToString());
return View("Success", baseSubmissionBindingModel);
}
如果用户提交表单时未提供所有必需的数据,则模型的状态无效。初始视图连同验证错误消息一起返回给用户。
但是,提交类别的选择框不再有从数据库检索的提交类别的任何选项。因此用户无法再选择提交类别。
如果用户最初未能提供所有必需的数据但仍提交表单,如何确保提交类别选择框仍然具有其选项元素?
谢谢您的帮助。
布鲁斯
当模型状态验证失败时,您将返回到具有 SELECT 标签助手的同一视图。您的选择标记帮助程序使用传递的视图模型的
SubmissionCategoryItems
属性作为源集合来构建 SELECT 元素的选项。 Http 是无状态的。对于您的第二次调用(表单提交调用),它不知道您在上一次调用中做了什么(您确实在 GET 操作调用中设置了这些集合项)。因此,每次返回使用该集合构建选择元素的视图时,您都需要设置集合属性值。
public IActionResult CreateSubmission(BaseSubmissionBindingModel model)
{
if (! ModelState.IsValid)
{
// Set the collection property value again
model.SubmissionCategoryItems = GetCategoryItems();
return View("Index", model);
}
//to do : do some thing useful
Log.Information("Submission data " + baseSubmissionBindingModel.ToString());
return View("Success", model);
}
private List<SelectListItem> GetCategoryItems()
{
var items = new List<SelectListItem>();
// TO DO : I hard coded 2 items. You can replace it with items from your database
items.Add(new SelectListItem() { Value = "1", Text = "Seattle" });
items.Add(new SelectListItem() { Value = "2", Text = "Detroit" });
return items;
}