Odráží hodnotu změněnou v akci po zaúčtování formuláře v zobrazení

Datum vytvoření stránky :

životní prostředí

Vizuální sada
  • Vizuální sada 2022
jádro ASP.NET
  • 6,0 MVC

Funguje v jiných prostředích, než je výše uvedené, ale publikovaný kód byl napsán ve výše uvedeném rámci.

Co dělat

Pokuste se vytvořit jednoduchý program, který říká: "Zveřejněte text, který jste zadali na obrazovce, a vraťte zpracovaný text na stejnou obrazovku jako nový výsledek."

kód

Základem je vytvoření nového projektu MVC, ze kterého přidáte kód. Kód je publikován pro celkovou konfiguraci, proto se na něj prosím podívejte.

Model (viewmodel)

Vytvořte následující model pro interakci zobrazení a akce: ResultValue Jsou dva, ale chtěl jsem dát dva výsledky v pohledu, takže jsem připravil dva.

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; }
  }
}

akce

Je to jednoduchý proces: zobrazit zobrazení, vzít text zadaný do POST, zpracovat jej a vrátit výsledek.

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);
    }
  }
}

pohled

Vytvářejte zobrazení na základě akcí a modelů.

Když kliknete ResultValue1 na tlačítko aktualizace a ResultValue2 zobrazí se, ale zobrazí se v "vstupním textu" a "ve značce 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 Přidejte odkaz, abyste mohli přejít z Sample na .

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>    @* 追加 *@

Aktualizace modelu přijatého v procesu POST nemá vliv na vstup pohledu atd.

Spusťte kód, který jste vytvořili výše, zadejte z InputValue ukázkové obrazovky a zkuste aktualizovat.

Na straně akce, ResultValue1 protože hodnoty jsou nastaveny a ResultValue2 vráceny, se předpokládá, že obě jsou původně zobrazeny, ale ve skutečnosti div jsou zobrazeny pouze 2 nastavené v tagu.

Hodnota nastavená na ModelState má přednost

Když klient POSTSuje vstupní hodnotu, hodnota je nastavena na proměnnou modelu argumentu ControllerBase.ModelState , ale hodnota je také nastavena. Zadaná hodnota je ModelState poté ověřena s hodnotou nastavenou na . ModelState.IsValid To je důvod, proč je posuzována. Při ladění můžete zkontrolovat obsah zastavením zpracování na zarážce.

Pokud jste původně chtěli vrátit hodnotu do zobrazení, je return View(model); v pořádku zahrnout , ale pokud je ModelState hodnota nastavena na ,ModelState hodnota má přednost a je vrácena do zobrazení.

ModelState Vzhledem k tomu, že hodnota nastavená na je hodnota odeslaná zadáním pohledu atd., Z hlediska InputValuemodelu, , ResultValue1 je nastavena. ResultValue1 Proto má přednost hodnota a ModelState hodnota nastavená v modelu,ModelState která není ResultValue2 nastavena na, se zobrazí v zobrazení.

Vrácení hodnoty do zobrazení ve prospěch hodnoty modelu

ModelState Hodnoty nastavené tak, aby měly přednost před zobrazením, takže pokud ModelState vymažete hodnoty nastavené na , hodnota modelu se vrátí do zobrazení.

ModelState.Clear() Všechny hodnoty, které má, můžete vymazat voláním následujícím způsobemModelState:

[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 program také provádí proces ověření,ModelState.Clear takže si jej při ModelState.IsValid volání přečtěte po volání .

Po spuštění se výsledek zobrazí správně následujícím způsobem.

ModelState.Clear Vzhledem k tomu, že všechny hodnoty zmizí při volání metody, je také možné zadat název vlastnosti modelu a vymazat hodnoty jednotlivě následujícím způsobem.

[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);
}