Odzwierciedlanie wartości zmienionej w akcji po opublikowaniu formularza w widoku
środowisko
- Visual Studio
-
- Program Visual Studio 2022
- Rdzeń ASP.NET
-
- 6,0 MVC
Działa w środowiskach innych niż powyższe, ale opublikowany kod został napisany w powyższym frameworku.
Co zrobić
Spróbuj utworzyć prosty program, który mówi: "Opublikuj wpisany tekst na ekranie i zwróć przetworzony tekst na ten sam ekran jako nowy wynik".
kod
Podstawą jest stworzenie nowego projektu MVC, z którego dodajesz kod. Kod jest publikowany dla ogólnej konfiguracji, więc proszę się z nim zapoznać.
Model (viewmodel)
Utwórz następujący model interakcji widoku i akcji: ResultValue
Są dwa, ale chciałem podać dwa wyniki w widoku, więc przygotowałem dwa.
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; }
}
}
akcja
To prosty proces: wyświetl widok, weź tekst wprowadzony w POST, przetwórz go i zwróć wynik.
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);
}
}
}
widok
Tworzenie widoków na podstawie akcji i modeli.
Po kliknięciu ResultValue1
przycisku aktualizacji i ResultValue2
są wyświetlane, ale są wyświetlane odpowiednio w "tekście wejściowym" i "w znaczniku 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
Dodaj łącze, aby móc przejść z Sample
do .
Indeks.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> @* 追加 *@
Aktualizacja modelu otrzymanego w procesie POST nie wpływa na wprowadzanie widoku itp.
Uruchom kod utworzony powyżej, wprowadź go na InputValue
ekranie Przykład i spróbuj zaktualizować.
Po stronie akcji, ResultValue1
ponieważ wartości są ustawione i ResultValue2
zwracane, zakłada się, że oba są pierwotnie wyświetlane, ale w rzeczywistości div
wyświetlane są tylko 2 ustawione w tagu.
Wartość ustawiona na ModelState ma pierwszeństwo
Gdy klient POST wartość wejściową, wartość jest ustawiana na zmienną modelu argumentu ControllerBase.ModelState
, ale wartość jest również ustawiana.
Wprowadzona wartość jest ModelState
następnie sprawdzana z wartością ustawioną na . ModelState.IsValid
Dlatego jest osądzany.
Podczas debugowania można sprawdzić zawartość, zatrzymując przetwarzanie w punkcie przerwania.
Jeśli pierwotnie chcesz zwrócić wartość do widoku, return View(model);
możesz dołączyć , ale jeśli wartość jest ModelState
ustawiona na ,ModelState
wartość ma pierwszeństwo i jest zwracana do widoku.
ModelState
Ponieważ wartość ustawiona na jest wartością wysłaną przez wprowadzenie widoku itp., W kategoriach InputValue
modelu, , jest ustawiona ResultValue1
.
ResultValue1
W związku z tym wartość ma pierwszeństwo ModelState
,ModelState
a wartość ustawiona w modelu, która nie ResultValue2
jest ustawiona na jest wyświetlana w widoku.
Aby zwrócić wartość do widoku na korzyść wartości modelu
ModelState
Wartości ustawione tak, aby miały pierwszeństwo przed widokiem, więc jeśli ModelState
usuniesz wartości ustawione na , wartość modelu zostanie zwrócona do widoku.
ModelState.Clear()
Możesz usunąć wszystkie wartości, które mają, wywołując ModelState
w następujący sposób:
[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
wykonuje również proces sprawdzania poprawności, więc pamiętajModelState.IsValid
,ModelState.Clear
aby przeczytać go po wywołaniu .
Po uruchomieniu wynik zostanie wyświetlony poprawnie w następujący sposób.
ModelState.Clear
Ponieważ wszystkie wartości znikają po wywołaniu metody, możliwe jest również określenie nazwy właściwości modelu i wymazanie wartości pojedynczo w następujący sposób.
[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);
}