将窗体发布后操作中更改的值传播到视图
环境
- Visual Studio
-
- Visual Studio 2022
- ASP.NET Core
-
- 6.0 MVC
它适用于其他环境,但您发布的代码是在上述框架中创建的。
你正在做的
尝试编写一个简单的程序,"开机自检您在屏幕上输入的文本,并将收到的文本作为新结果返回到同一屏幕"。
代码
该基础是创建新的 MVC 项目,并从那里添加代码。 有关整个配置,请参阅此处的代码。
模型(视图模型)
为视图和操作之间的交互创建以下模型: ResultValue
有两个,但我想在视图中显示两个结果,所以我准备了两个。
SampleViewModel
namespace PostValueChange.Models
{
public class SampleViewModel
{
<summary>入力値を受け取るプロパティ。</summary>
public string? InputValue { get; set; }
<summary>結果を出力するプロパティ。</summary>
public string? ResultValue1 { get; set; }
<summary>結果を出力するプロパティ。</summary>
public string? ResultValue2 { get; set; }
}
}
行动
在 GET 中显示视图,接受在开机自检中输入的文本,然后处理并返回结果。
HomeController
// 省略
namespace PostValueChange.Controllers
{
public class HomeController : Controller
{
// 省略
[HttpGet]
public IActionResult Sample() => View();
[HttpPost]
public IActionResult Sample(SampleViewModel model)
{
if (ModelState.IsValid == false) View(model);
model.ResultValue1 = model.InputValue + " テキストを追加1";
model.ResultValue2 = model.InputValue + " テキストを追加2";
return View(model);
}
}
}
视图
基于操作和模型创建视图。
当我单击更新按钮时 ResultValue1
,我尝试显示 和 ResultValue2
,但每个按钮都显示在"输入文本"和"div 标记中"中。
Sample.cshtml
@model PostValueChange.Models.SampleViewModel
@{
ViewData["Title"] = "Sample";
}
<h1>Sample</h1>
<h4>SampleViewModel</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Sample" >
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="InputValue" class="control-label"></label>
<input asp-for="InputValue" class="form-control" />
<span asp-validation-for="InputValue" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="更新" class="btn btn-primary" />
</div>
<div class="form-group">
<label asp-for="ResultValue1" class="control-label"></label>
<input asp-for="ResultValue1" class="form-control" />
<span asp-validation-for="ResultValue1" class="text-danger"></span>
</div>
<div>@Model?.ResultValue2</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">前の画面に戻る</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Index.cshtml
Sample
添加链接,以便可以从 转换到 。
Index.cshtml
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
<a asp-action="Sample">Sample</a> @* 追加 *@
更新 POST 处理接收的模型不会反映在视图输入等中。
运行上面编写的代码,然后尝试从 InputValue
示例屏幕输入 并更新 。
由于 ResultValue1
操作端将 值设置为 和 ResultValue2
返回,因此最初假定同时显示两者, div
但实际上仅显示在标记中设置的 2。
为模型状态设置的值优先
当从客户端开机自检输入值时,该值将设置为参数的模型变量, ControllerBase.ModelState
但其他值将设置为其他值。
然后,使用设置为 的值验证 ModelState
输入的值。 ModelState.IsValid
这也是我们能够做出判断的原因。
如果在调试时在断点处停止处理,则可以看到内容。
如果最初将值返回给视图, return View(model);
则按 如下所述,但ModelState
如果 设置为 ,则 ModelState
的值优先并返回到视图。
ModelState
设置为 的值是输入和发送的值,例如视图的输入,因此在 InputValue
模型中,设置 ResultValue1
的状态为 。
因此,ResultValue1
的 ModelState
值优先,ModelState
而 未 ResultValue2
设置为 的 值显示在视图中。
将值返回给视图以覆盖模型值
如上所述 ModelState
,设置为 的值将优先返回到视图,因此,如果删除设置为 相反 ModelState
的值,则模型的值将返回到视图。
您可以通过 ModelState
调用 来擦除 具有的所有值,如下所示 ModelState.Clear()
:
[HttpPost]
public IActionResult Sample(SampleViewModel model)
{
if (ModelState.IsValid == false) View(model);
// ModelState の値を消してモデルの値をビューに返却できるようにする
ModelState.Clear();
// ビューに返す値を設定する
model.ResultValue1 = model.InputValue + " テキストを追加1";
model.ResultValue2 = model.InputValue + " テキストを追加2";
return View(model);
}
ModelState
也执行验证过程,因此在ModelState.Clear
调用 时,请确保 ModelState.IsValid
在 之后阅读 。
这将确保结果正确显示,如下所示:
ModelState.Clear
由于调用 方法时所有值都将消失,因此可以通过指定模型的属性名称来单独擦除该值,如下所示:
[HttpPost]
public IActionResult Sample(SampleViewModel model)
{
if (ModelState.IsValid == false) View(model);
// ModelState の値を消してモデルの値をビューに返却できるようにする
ModelState.Remove(nameof(model.ResultValue1));
// ビューに返す値を設定する
model.ResultValue1 = model.InputValue + " テキストを追加1";
model.ResultValue2 = model.InputValue + " テキストを追加2";
return View(model);
}