將表單發佈後操作中更改的值傳播到檢視
環境
- 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);
}