عكس القيمة التي تم تغييرها في الإجراء بعد نشر النموذج في طريقة العرض

تاريخ إنشاء الصفحة :

وسط

استوديو مرئي
  • فيسوال ستوديو 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 النقر فوق الزر تحديث ، ويتم عرضها ، ولكن يتم عرضها في "نص الإدخال" و "في علامة div" ، ResultValue2 على التوالي.

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 أضف رابطا بحيث يمكنك الانتقال من 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>    @* 追加 *@

لا يؤثر تحديث النموذج المستلم في عملية POST على إدخال طريقة العرض ، إلخ.

قم بتشغيل التعليمة البرمجية التي أنشأتها أعلاه، وأدخل من InputValue شاشة عينة، وحاول تحديثها.

على جانب الإجراء ، نظرا لأنه يتم تعيين القيم وإرجاعها ResultValue2 ، فمن المفترض أن يتم عرض كليهما في الأصل ، ResultValue1 ولكن في الواقع div يتم عرض مجموعة 2 فقط في العلامة.

القيمة المعينة إلى ModelState لها الأسبقية

عندما يقوم العميل POSTs قيمة الإدخال، يتم تعيين القيمة إلى متغير نموذج الوسيطة ControllerBase.ModelState ، ولكن يتم تعيين القيمة أيضا. ثم يتم ModelState التحقق من صحة القيمة التي تم إدخالها مع تعيين القيمة إلى . ModelState.IsValid هذا هو السبب في الحكم عليه. عند تصحيح الأخطاء ، يمكنك التحقق من المحتويات عن طريق إيقاف المعالجة عند نقطة التوقف.

إذا كنت تريد في الأصل إرجاع قيمة إلى طريقة العرض، فلا return View(model); بأس من تضمينها، ولكن إذا تم تعيين قيمة ModelState إلى ،ModelState فإن قيمة لها الأسبقية ويتم إرجاعها إلى طريقة العرض.

ModelStateنظرا لأن القيمة التي تم تعيينها إلى هي قيمة يتم إرسالها عن طريق إدخال طريقة العرض ، وما إلى ذلك ، من InputValueحيث النموذج ، ResultValue1 يتم تعيينها. لذلك، فإن قيمة يأخذ ModelState الأسبقية،ResultValue1ModelState ويتم عرض القيمة التي تم تعيينها في النموذج الذي لم 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);
}