【发布时间】:2018-02-19 15:17:19
【问题描述】:
我已经从 MVC 项目模板生成了一个简单的 ASP.NET Core MVC 应用程序。 HomeController 已被修改以公开两个 Index 方法重载——一个用于 GET,一个用于 POST 请求,两者都使用简单的 BooleanInputsViewModel 呈现相同的 Index.cshtml 视图:
public class BooleanInputsViewModel
{
public bool IsImportant { get; set; }
public bool IsActive { get; set; }
public List<string> Messages { get; } = new List<string>();
}
Index.cshtml 视图如下所示:
@model AspNetCoreBooleanInputs.Models.BooleanInputsViewModel
<h2>
@nameof(this.Model.IsImportant) = @this.Model.IsImportant.ToString()
<br />
@nameof(this.Model.IsActive) = @this.Model.IsActive.ToString()
</h2>
<form class="form-horizontal" method="post">
<div class="col-md-12">
<input asp-for="IsImportant" />
<label asp-for="IsImportant">
</label>
<input asp-for="IsActive" />
<label asp-for="IsActive">
</label>
</div>
<div class="col-md-12">
<ul>
@foreach(string message in this.Model.Messages)
{
<li>@message</li>
}
</ul>
</div>
<div class="col-md-12">
<button type="submit">Submit</button>
</div>
</form>
最后,HomeControllerIndex 方法是这样实现的:
public IActionResult Index()
{
var model = new BooleanInputsViewModel();
model.Messages.Add($"GET values: {nameof(model.IsImportant)} = {model.IsImportant}, {nameof(model.IsActive)} = {model.IsActive}");
return View(model);
}
[HttpPost]
public IActionResult Index(BooleanInputsViewModel model)
{
model.Messages.Add($"POST values: {nameof(model.IsImportant)} = {model.IsImportant}, {nameof(model.IsActive)} = {model.IsActive}");
model.IsActive = !model.IsActive;
model.IsImportant = !model.IsImportant;
model.Messages.Add($"Negated POST values: {nameof(model.IsImportant)} = {model.IsImportant}, {nameof(model.IsActive)} = {model.IsActive}");
return this.View(model);
}
POST 处理程序否定两个模型属性并将修改后的模型传递回视图。但是,否定值不会反映在呈现的表单中,因为它总是呈现最初的 POST 值。对我来说,这看起来像一个错误。我错过了什么明显的东西吗?
完整的 ASP.NET Core 项目发布在这里 - https://github.com/PaloMraz/AspNetCoreBooleanInputs。
根据以下@Chris Platt 的回答进行编辑:
嗨,克里斯,感谢您的及时答复。我已经验证使用您建议的 ModelState 字典可以按预期工作,例如:
[HttpPost]
public IActionResult Index(BooleanInputsViewModel model)
{
model.Messages.Add($"POST values: {nameof(model.IsImportant)} = {model.IsImportant}, {nameof(model.IsActive)} = {model.IsActive}");
// This does NOT work:
//model.IsActive = !model.IsActive;
//model.IsImportant = !model.IsImportant;
// This works:
this.ModelState[nameof(model.IsActive)].RawValue = !model.IsActive;
this.ModelState[nameof(model.IsImportant)].RawValue = !model.IsImportant;
model.Messages.Add($"Negated POST values: {nameof(model.IsImportant)} = {model.IsImportant}, {nameof(model.IsActive)} = {model.IsActive}");
return this.View(model);
}
但是,我仍然觉得这是一个非常麻烦的行为,因为一旦调用了 Index 方法,模型就已经被绑定了。为什么在调用View 方法时再次发生绑定,有效地忽略了传入的model 实例?这对我来说看起来不对,抱歉。
另外,你能告诉我你从哪里得到关于ModelState字典组成的信息吗? https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding 的官方文档没有提到 ViewData/ViewBag 作为来源;只有表单值、路由值和查询字符串...
【问题讨论】:
标签: asp.net-core-mvc model-binding