Asp.Net 核心 1.1 ViewModel 在表单后为空 Post
Asp.Net Core 1.1 ViewModel Null after Form Post
我有一个名为 ResultsViewModel 的视图模型,我曾在 asp.net 核心 mvc 1.1 中强类型创建视图。它有 5 个下拉菜单和一些输入字段,如下面的代码所示:
这是视图模型
public class ResultsViewModel
{
public ResultsViewModel()
{
}
[Display(Name = "Students")]
public SelectList Students { get; set; }
[Display(Name = "Subjects")]
public SelectList Subjects { get; set; }
[Display(Name = "Term")]
public Term Terms { get; set; }
[Display(Name = "Continuous Assessment")]
public SelectList ContinuousAssessments { get; set; }
[Display(Name = "Continuous Assessment Score")]
[DisplayFormat(DataFormatString ="{0:F2}")]
public double CAScore { get; set; }
[Display(Name = "School Year")]
public SelectList Session { get; set; }
[Display(Name = "Class")]
public SelectList Class { get; set; }
[Display(Name = "Average Score")]
[DisplayFormat(DataFormatString = "{0:F2}")]
public double AverageScore { get; set; }
[Display(Name = "Term Total Score")]
[DisplayFormat(DataFormatString = "{0:F2}")]
public double TermTotal { get; set; }
}
这是创建视图。它的标准没有什么特别的
@model SwiftSchool.ViewModels.ResultsViewModel
@{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<form asp-action="Create" method="post">
<div class="form-horizontal">
<h4>Result</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Students" class="col-md-2 control-label"></label>
<div class="col-md-10">
@Html.DropDownList("Student", Model.Students, "Select Student", new { @class = "form-control", @id = "studentselect" })
</div>
</div>
<div class="form-group">
<label asp-for="Subjects" class="col-md-2 control-label"></label>
<div class="col-md-10">
@Html.DropDownList("Subject", Model.Subjects, "Select Subject", new { @class = "form-control", @id = "subjectselect" })
</div>
</div>
<div class="form-group">
<label asp-for="Session" class="col-md-2 control-label"></label>
<div class="col-md-10">
@Html.DropDownList("Session", Model.Session, "Select School Session",
new { @class = "form-control", @id = "sessionselect" })
</div>
</div>
<div class="form-group">
<label asp-for="Class" class="col-md-2 control-label"></label>
<div class="col-md-4">
@Html.DropDownList("Class", Model.Class, "Select Student Class",
new { @class = "form-control", @id = "classselect" })
</div>
</div>
<div class="form-group">
<label asp-for="ContinuousAssessments" class="col-md-2 control-label"></label>
<div class="col-md-10">
@Html.DropDownList("C.A", Model.ContinuousAssessments, "Select C.A",
new { @class = "form-control", @id = "caselect" })
</div>
</div>
<div class="form-group">
<label asp-for="CAScore" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="CAScore" class="form-control" readonly id="cascore" />
<span asp-validation-for="CAScore" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="AverageScore" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="AverageScore" class="form-control" />
<span asp-validation-for="AverageScore" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="TermTotal" class="col-md-2 control-label"</label>
<div class="col-md-10">
<input asp-for="TermTotal" class="form-control" />
<span asp-validation-for="TermTotal" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default"/>
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
我有表单提交并返回我的 ResultsViewModel 到我的控制器。为视图创建下拉列表的两种方法和处理 POST 的方法如下所示:
// GET: Result/Create
public IActionResult Create()
{
var rim = new ResultsViewModel();
rim.Students = new SelectList(_context.Students.ToList(), "Id", "FullName");
rim.Subjects = new SelectList(_context.Subjects.ToList(), "Id", "Name");
rim.ContinuousAssessments = new SelectList(_context.ContinuousAssessment.ToList(), "Id", "Name");
rim.Class = new SelectList(_context.Classes.ToList(), "Id", "ClassName");
rim.Session = new SelectList(_context.Sessions.ToList(), "Id", "SessionName");
return View(rim);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(ResultsViewModel model)
{
if (ModelState.IsValid)
{
_context.Add(model);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(model);
}
}
因此,当我在选择并填写表单上的所有字段后对表单执行 POST 时,我在检查 ModelState 是否有效的地方设置了一个断点,并检查了注入的视图模型Create 方法,一切都是空的,尤其是下拉菜单。所以一切都从那里向南发展。有人可以让我知道发生了什么事吗?因为我觉得这很烦人。我希望这不是框架中的另一个错误,因为我在网上某处看到这是框架早期版本中的错误。无论如何,我们将不胜感激。
您创建的下拉列表与模型中的任何属性都没有关系。
第一个绑定到不存在的名为 Student
的 属性。第二个绑定到名为 Subject
的 属性,但它又不存在。第 3 个绑定到 属性 Session
,它是复杂对象的集合 (IEnumerable<SelectListItem>
),但 <select>
元素仅回发一个值 - 所选选项的值。第四次也是如此。
您的模型需要绑定属性
[Display(Name = "Students")]
[Required("Please select a student")]
public int SelectedStudent { get; set; }
public IEnumerable<SelectListItem> Students { get; set; }
然后在视图中
@Html.DropwDownListFor(m => m.SelectedStudent, Model.Students, "Select Student", new { @class = "form-control" })
请注意,不清楚为什么您使用 new { @id = "studentselect" }
覆盖方法生成的默认 id
属性(即 id="SelectedStudent"
)
或者,使用标签助手
<select asp-for="SelectedStudent" asp-items="Model.Students" class="form-control">
<option>Select Student</option>
</select>
如果您为那些 属性 类型提交了有效值,则使用生成的 3 个输入将绑定良好。
旁注:在 POST 方法中,您需要在 return 模型到视图之前重新填充 SelectLists,否则它们将是 null
并且会出现异常抛出 - 参考
我有一个名为 ResultsViewModel 的视图模型,我曾在 asp.net 核心 mvc 1.1 中强类型创建视图。它有 5 个下拉菜单和一些输入字段,如下面的代码所示:
这是视图模型
public class ResultsViewModel
{
public ResultsViewModel()
{
}
[Display(Name = "Students")]
public SelectList Students { get; set; }
[Display(Name = "Subjects")]
public SelectList Subjects { get; set; }
[Display(Name = "Term")]
public Term Terms { get; set; }
[Display(Name = "Continuous Assessment")]
public SelectList ContinuousAssessments { get; set; }
[Display(Name = "Continuous Assessment Score")]
[DisplayFormat(DataFormatString ="{0:F2}")]
public double CAScore { get; set; }
[Display(Name = "School Year")]
public SelectList Session { get; set; }
[Display(Name = "Class")]
public SelectList Class { get; set; }
[Display(Name = "Average Score")]
[DisplayFormat(DataFormatString = "{0:F2}")]
public double AverageScore { get; set; }
[Display(Name = "Term Total Score")]
[DisplayFormat(DataFormatString = "{0:F2}")]
public double TermTotal { get; set; }
}
这是创建视图。它的标准没有什么特别的
@model SwiftSchool.ViewModels.ResultsViewModel
@{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<form asp-action="Create" method="post">
<div class="form-horizontal">
<h4>Result</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Students" class="col-md-2 control-label"></label>
<div class="col-md-10">
@Html.DropDownList("Student", Model.Students, "Select Student", new { @class = "form-control", @id = "studentselect" })
</div>
</div>
<div class="form-group">
<label asp-for="Subjects" class="col-md-2 control-label"></label>
<div class="col-md-10">
@Html.DropDownList("Subject", Model.Subjects, "Select Subject", new { @class = "form-control", @id = "subjectselect" })
</div>
</div>
<div class="form-group">
<label asp-for="Session" class="col-md-2 control-label"></label>
<div class="col-md-10">
@Html.DropDownList("Session", Model.Session, "Select School Session",
new { @class = "form-control", @id = "sessionselect" })
</div>
</div>
<div class="form-group">
<label asp-for="Class" class="col-md-2 control-label"></label>
<div class="col-md-4">
@Html.DropDownList("Class", Model.Class, "Select Student Class",
new { @class = "form-control", @id = "classselect" })
</div>
</div>
<div class="form-group">
<label asp-for="ContinuousAssessments" class="col-md-2 control-label"></label>
<div class="col-md-10">
@Html.DropDownList("C.A", Model.ContinuousAssessments, "Select C.A",
new { @class = "form-control", @id = "caselect" })
</div>
</div>
<div class="form-group">
<label asp-for="CAScore" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="CAScore" class="form-control" readonly id="cascore" />
<span asp-validation-for="CAScore" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="AverageScore" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="AverageScore" class="form-control" />
<span asp-validation-for="AverageScore" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="TermTotal" class="col-md-2 control-label"</label>
<div class="col-md-10">
<input asp-for="TermTotal" class="form-control" />
<span asp-validation-for="TermTotal" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default"/>
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
我有表单提交并返回我的 ResultsViewModel 到我的控制器。为视图创建下拉列表的两种方法和处理 POST 的方法如下所示:
// GET: Result/Create
public IActionResult Create()
{
var rim = new ResultsViewModel();
rim.Students = new SelectList(_context.Students.ToList(), "Id", "FullName");
rim.Subjects = new SelectList(_context.Subjects.ToList(), "Id", "Name");
rim.ContinuousAssessments = new SelectList(_context.ContinuousAssessment.ToList(), "Id", "Name");
rim.Class = new SelectList(_context.Classes.ToList(), "Id", "ClassName");
rim.Session = new SelectList(_context.Sessions.ToList(), "Id", "SessionName");
return View(rim);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(ResultsViewModel model)
{
if (ModelState.IsValid)
{
_context.Add(model);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(model);
}
}
因此,当我在选择并填写表单上的所有字段后对表单执行 POST 时,我在检查 ModelState 是否有效的地方设置了一个断点,并检查了注入的视图模型Create 方法,一切都是空的,尤其是下拉菜单。所以一切都从那里向南发展。有人可以让我知道发生了什么事吗?因为我觉得这很烦人。我希望这不是框架中的另一个错误,因为我在网上某处看到这是框架早期版本中的错误。无论如何,我们将不胜感激。
您创建的下拉列表与模型中的任何属性都没有关系。
第一个绑定到不存在的名为 Student
的 属性。第二个绑定到名为 Subject
的 属性,但它又不存在。第 3 个绑定到 属性 Session
,它是复杂对象的集合 (IEnumerable<SelectListItem>
),但 <select>
元素仅回发一个值 - 所选选项的值。第四次也是如此。
您的模型需要绑定属性
[Display(Name = "Students")]
[Required("Please select a student")]
public int SelectedStudent { get; set; }
public IEnumerable<SelectListItem> Students { get; set; }
然后在视图中
@Html.DropwDownListFor(m => m.SelectedStudent, Model.Students, "Select Student", new { @class = "form-control" })
请注意,不清楚为什么您使用 new { @id = "studentselect" }
覆盖方法生成的默认 id
属性(即 id="SelectedStudent"
)
或者,使用标签助手
<select asp-for="SelectedStudent" asp-items="Model.Students" class="form-control">
<option>Select Student</option>
</select>
如果您为那些 属性 类型提交了有效值,则使用生成的 3 个输入将绑定良好。
旁注:在 POST 方法中,您需要在 return 模型到视图之前重新填充 SelectLists,否则它们将是 null
并且会出现异常抛出 - 参考