Отразить значение, измененное в действии после записи формы в представлении

Дата создания страницы :

окружающая среда

Visual Studio
  • Visual Studio 2022
ASP.NET Ядро
  • 6.0 MVC

Он работает в средах, отличных от вышеуказанных, но опубликованный код был написан в фреймворке выше.

Что делать

Попробуйте создать простую программу, которая говорит: «Разместите текст, который вы ввели, на экране и верните обработанный текст на тот же экран в качестве нового результата».

код

Базой является создание нового проекта MVC, из которого добавляется код. Код публикуется для общей конфигурации, поэтому, пожалуйста, обратитесь к нему.

Модель (видмодель)

Создайте следующую модель для взаимодействия представления и действия: ResultValue Их два, но я хотел дать два результата в представлении, поэтому подготовил два.

ОбразецВидедель

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

действие

Это простой процесс: отобразить представление, взять текст, введенный в POST, обработать его и вернуть результат.

ГлавнаяКонтроллер

// 省略

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» соответственно.

Образец.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 к .

Индекс.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, установленные в теге.

Значение, задаваемое значение ModelState, имеет приоритет

Когда клиент отправляет входное значение, оно задается переменной модели аргумента ControllerBase.ModelState , но значение также задается. Введенное значение затем проверяется ModelState со значением , установленным в . ModelState.IsValid Вот почему о нем судят. При отладке можно проверить содержимое, остановив обработку в точке останова.

Если изначально требуется return View(model); вернуть значение представлению, можно включить , но если задано ModelState значение ,ModelState значение имеет приоритет и возвращается в представление.

ModelState Поскольку значение, заданное в значение, является значением, отправленным путем ввода представления и т. д., в терминах InputValueмодели, задано значение. ResultValue1 ПоэтомуResultValue1 значение имеет ModelState приоритет, а значение,ModelState заданное в модели, которое не ResultValue2 задано значением, отображается в представлении.

Возврат значения представлению в пользу значения модели

ModelState Значения, заданные для приоритета представления, поэтому при ModelState стирании значений, заданных в значение , значение модели будет возвращено представлению.

ModelState.Clear() Вы можете стереть все имеющиеся значения, вызвав ModelState следующий вызов:

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