Reflejar el valor cambiado en la acción después de la publicación del formulario en la vista

Fecha de creación de la página :

medio ambiente

Visual Studio
  • Visual Studio 2022
núcleo ASP.NET
  • 6.0 MVC

Funciona en entornos distintos a los anteriores, pero el código publicado se escribió en el marco anterior.

Qué hacer

Intente crear un programa simple que diga: "Publique el texto que escribió en la pantalla y devuelva el texto procesado a la misma pantalla como un nuevo resultado".

código

La base es la creación de un nuevo proyecto MVC, a partir del cual se agrega código. El código se publica para la configuración general, así que por favor refiérase a él.

Modelo (viewmodel)

Cree el siguiente modelo para la interacción de vista y acción: ResultValue Hay dos, pero quería dar dos resultados en la vista, así que preparé dos.

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

acción

Es un proceso simple: llegar a mostrar la vista, tomar el texto ingresado en POST, procesarlo y devolver el resultado.

HomeControlador

// 省略

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

Cree vistas basadas en acciones y modelos.

Cuando hace ResultValue1 clic en el botón de actualización, y ResultValue2 se muestran, pero se muestran en "texto de entrada" y "en etiqueta div", respectivamente.

Ejemplo.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 Agregue un vínculo para que pueda hacer la transición 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>    @* 追加 *@

La actualización del modelo recibido en el proceso POST no afecta a la entrada de la vista, etc.

Ejecute el código que creó anteriormente, escriba desde InputValue la pantalla Ejemplo e intente actualizar.

En el lado de la acción, ResultValue1 dado que los valores se establecen y ResultValue2 devuelven, se supone que ambos se muestran originalmente, pero de hecho div solo se muestran los 2 conjuntos en la etiqueta.

El valor establecido en ModelState tiene prioridad

Cuando el cliente POST el valor de entrada, el valor se establece en la variable de modelo del ControllerBase.ModelState argumento, pero también se establece el valor. A continuación, el valor introducido se ModelState valida con el valor establecido en . ModelState.IsValid Por eso se juzga. Al depurar, puede comprobar el contenido deteniendo el procesamiento en el punto de interrupción.

Si originalmente desea devolver un valor a la vista, está return View(model); bien incluir , pero si un valor se ModelState establece en ,ModelState el valor de tiene prioridad y se devuelve a la vista.

ModelState Dado que el valor establecido en es un valor enviado al introducir la vista, etc., en términos del InputValuemodelo, , ResultValue1 se establece. Por lo tanto,ResultValue1 el valor de tiene ModelState prioridadModelState y el valor establecido en el modelo que no ResultValue2 está establecido en se muestra en la vista.

Para devolver un valor a una vista a favor de un valor de modelo

ModelState Los valores se establecen para que tengan prioridad en la vista, por lo que si ModelState borra los valores establecidos en , el valor del modelo se devolverá a la vista.

ModelState.Clear() Puede borrar todos los valores que tiene llamando ModelState de la siguiente manera:

[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 también está haciendo el proceso de validación,ModelState.Clear así que asegúrese de ModelState.IsValid leerlo después de cuando llame.

Cuando lo ejecute, el resultado se mostrará correctamente de la siguiente manera.

ModelState.Clear Dado que todos los valores desaparecen cuando se llama a un método, también es posible especificar el nombre de propiedad del modelo y borrar los valores individualmente de la siguiente manera.

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