Reflita o valor alterado na ação após o post do formulário na exibição

Data de criação de página :

ambiente

Estúdio Visual
  • Visual Studio 2022
Núcleo ASP.NET
  • 6.0 MVC

Funciona em ambientes diferentes dos acima, mas o código publicado foi escrito no quadro acima.

O que fazer

Tente criar um programa simples que diz: "Poste o texto digitado na tela e devolva o texto processado para a mesma tela que um novo resultado."

código

A base é a criação de um novo projeto MVC, a partir do qual você adiciona código. O código é publicado para a configuração geral, então por favor, consulte-o.

Modelo (modelo de exibição)

Crie o seguinte modelo para interação de exibição e ação: ResultValue Há dois, mas eu queria dar dois resultados na vista, então eu preparei dois.

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

ação

É um processo simples: exibir a exibição, pegar o texto inserido no POST, processá-lo e devolver o resultado.

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

vista

Crie visualizações baseadas em ações e modelos.

Quando você ResultValue1 clica no botão de atualização e ResultValue2 é exibido, mas eles são exibidos em "texto de entrada" e "na tag div", respectivamente.

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 Adicione um link para que você possa fazer a transição de 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>    @* 追加 *@

Atualizar o modelo recebido no processo POST não afeta a entrada da visualização, etc.

Execute o código que você criou acima, insira InputValue na tela 'Amostrar' e tente atualizar.

No lado da ação, ResultValue1 uma vez que os valores são definidos para e ResultValue2 devolvidos, presume-se que ambos são exibidos originalmente, mas na verdade div apenas os 2 definidos na tag são exibidos.

O valor definido para ModelState tem precedência

Quando o cliente POSTs o valor de entrada, o valor é definido para a variável modelo do ControllerBase.ModelState argumento, mas o valor também é definido. O valor inserido é ModelState então validado com o valor definido para . ModelState.IsValid É por isso que é julgado. Ao depurar, você pode verificar o conteúdo parando o processamento no ponto de interrupção.

Se você originalmente deseja retornar um valor para a exibição, não há return View(model); problema em incluir , mas se um valor for ModelState definido,ModelState o valor de tem precedência e é devolvido à vista.

ModelState Uma vez que o valor definido é um valor enviado inserindo a visualização, etc., em termos do InputValuemodelo, , ResultValue1 é definido. Portanto,ResultValue1 o valor de prevalece ModelState ,ModelState e o valor definido no modelo que não ResultValue2 está definido é exibido na exibição.

Para devolver um valor a uma visão em favor de um valor de modelo

ModelState Os valores definidos para prevalecer à visão, portanto, se ModelState você apagar os valores definidos para , o valor do modelo será devolvido à vista.

ModelState.Clear() Você pode apagar todos os valores que tem ModelState ligando da seguinte forma:

[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 também está fazendo o processo de validação,ModelState.Clear por isso não deixe de ModelState.IsValid lê-lo depois quando você ligar .

Quando você executá-lo, o resultado será exibido corretamente da seguinte forma.

ModelState.Clear Como todos os valores desaparecem quando você chama um método, também é possível especificar o nome da propriedade do modelo e apagar os valores individualmente da seguinte forma.

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