Hỗ trợ đa ngôn ngữ cho điều hướng dữ liệu cho tên tham số và thư xác minh đầu vào

Ngày tạo trang :

Môi trường

ASP.NET Core
  • 5.0 MVC

Tiền đề

Lời nhắc này có nghĩa là bạn hiểu các mẹo sau:

Ngoài ra, nếu bạn muốn tạo một dự án mới, hãy thêm các tệp và mã sau theo lời nhắc ở trên:

  • tạo SharedResource.resx (+ en, es) 文件。 (Nội dung có thể trống rỗng)
  • Tạo tệp .cs tài nguyên được chia sẻ
  • Thêm mã bản địa hóa vào dịch vụ khởi động. Cấu hình
  • Thêm mã bản địa hóa vào Bắt đầu. Cấu hình

.cs khởi động đã được sửa chữa

Vì bạn cần các cài đặt đa ngôn ngữ khác liên quan đến thông báo dữ liệu, Startup.ConfigureServices hãy sửa đổi phương pháp như sau:

public void ConfigureServices(IServiceCollection services)
{
  services.AddControllersWithViews();

  services.AddMvc()
    // ローカライズに必要。Resx ファイルのフォルダパスを指定
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = "Resources"; })
    // DataAnnotations のローカライズに必要 (追加)
    .AddDataAnnotationsLocalization(options =>
     {
       // DataAnnotation を使ったときのメッセージは SharedResource に集約する
       options.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(SharedResource));
     });
}

Mô hình hóa đầu vào

Tạo mô hình để liên kết với màn hình đầu vào. Ví dụ này tạo ra nhiều thuộc tính để chứa các điều khiển đầu vào khác nhau. Nếu bạn gặp rắc rối khi tạo chúng, chỉ cần tạo một hoặc hai.

Trong thư mục Mô hình, tạo .cs mô hình xem người dùng.

Mã trông như thế này: Không gian tên phải được căn chỉnh một cách thích hợp. Các thuộc tính bạn đặt không liên quan đến đa ngôn ngữ vì chúng chỉ gán chúng. Hỗ trợ đa ngôn ngữ sẽ diễn ra trong tương lai.

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace LocalizationDataAnnotation.Models
{
  public class UserViewModel
  {
    [Required]
    [Display(Name = "ID (半角英数字)")]
    [StringLength(20)]
    [RegularExpression(@"^[0-9a-zA-Z]*$")]
    public string ID { get; set; }

    [StringLength(50)]
    public string Name { get; set; }

    [StringLength(50, MinimumLength = 8)]
    [DataType(DataType.Password)]
    [RegularExpression(@"^[0-9a-zA-Z]*$", ErrorMessage = "Password")]
    public string Password { get; set; }

    // 省略
  }

  // 省略
}

Tạo hành động

Tạo hành động và đăng ký trong để hiển thị màn hình đăng ký của người HomeController dùng.

Tạo màn hình và hành động là phù hợp vì đây không phải là chủ đề gợi ý. Ngoài ra, nó không thực hiện quá trình đăng ký thực tế.

// 初期コードは省略

namespace LocalizationDataAnnotation.Controllers
{
  public class HomeController : Controller
  {
    // 初期コードは省略

    public IActionResult Create()
    {
      return View();
    }

    [HttpPost]
    public IActionResult Create(UserViewModel model)
    {
      // エラーなら差し戻し
      if (ModelState.IsValid == false) return View(model);

      // 正常に登録できた場合は Index に戻る
      return RedirectToAction(nameof(Index));
    }
  }
}

Liên kết đến màn hình đăng ký người dùng

Tạo liên kết đến màn hình đăng ký của người dùng trong Dạng xem\Home\Index.cshtml. Miễn là chuyển đổi màn hình có thể, làm thế nào để viết không quan trọng.

asp-route-culture Thuộc tính mở trang bằng ngôn ngữ được chỉ định.

<!-- 初期コード省略 -->

<ul>
  <li><a asp-action="Create">Create</a></li>
  <li><a asp-action="Create" asp-route-culture="ja">Create (ja)</a></li>
  <li><a asp-action="Create" asp-route-culture="en">Create (en)</a></li>
  <li><a asp-action="Create" asp-route-culture="es">Create (es)</a></li>
</ul>

Tạo màn hình đăng ký người dùng

Create Nhấp chuột phải vào hành động và chọn Thêm dạng xem.

Chọn Chế độ xem Lazer.

Đặt mẫu thành Tạo và lớp mô hình thành Mô hình chế độ xem người dùng. Nếu bạn đang sử dụng UserViewModel mã mẫu, mã cũng sẽ chú thích. Khi bạn tạo mã trong giá đỡ, nó là sai để đặt các thuộc tính trong một thuộc tính cụ thể. Trước khi tạo dạng xem, hãy tạm thời chú thích chế độ xem.

Nếu bạn gặp lỗi khi tạo Razor, hãy tạo chế độ xem Razor trống và nhập mã sau.

@model LocalizationDataAnnotation.Models.UserViewModel
@using System.Globalization;
@{
  ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>UserViewModel</h4>
<hr />
<div class="row">
  <div class="col-md-4">
    <form asp-action="Create">
      <div asp-validation-summary="ModelOnly" class="text-danger"></div>
      <div class="form-group">
        <label asp-for="ID" class="control-label"></label>
        <input asp-for="ID" class="form-control" />
        <span asp-validation-for="ID" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Name" class="control-label"></label>
        <input asp-for="Name" class="form-control" />
        <span asp-validation-for="Name" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Password" class="control-label"></label>
        <input asp-for="Password" class="form-control" />
        <span asp-validation-for="Password" class="text-danger"></span>
      </div>

      <!-- 省略 -->

      <div class="form-group">
        <input type="submit" value="Create" class="btn btn-primary" asp-route-culture="@CultureInfo.CurrentCulture.Name" />
      </div>
    </form>
  </div>
</div>

<div>
  <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
  @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Bây giờ chúng ta hãy thử chạy nó để xem nếu chúng ta có thể xây dựng mã thành công và hiển thị màn hình một cách chính xác.

Đăng ký văn bản đa ngôn ngữ cho điều hướng dữ liệu

Chúng tôi sẽ thảo luận và, bởi vì tất cả các thuộc tính sẽ dài ID Name hơn. Đối với các thuộc tính khác, bạn có thể sử dụng các kỹ thuật tương tự để xử lý đa ngôn ngữ, vì vậy hãy thử từng thuộc tính.

Dưới đây là hỗ trợ đa ngôn ngữ cho các văn bản sau:

văn bản đa ngôn ngữ
Phím
Các tham số của ID hiển thị tên ID_DisplayName
Thông báo lỗi khi ID không được nhập Validate_Required
ID nhập thông báo lỗi khi số ký tự vượt quá 20 ký tự Validate_StringLength
Thông báo lỗi khi nhập ký tự không phải chữ và số bằng ID Validate_Alphanumeric
Tham số tên hiển thị tên Name_DisplayName
Thông báo lỗi khi tên được nhập hơn 50 ký tự Validate_StringLength

Validate_XXXXX Nên được phổ quát. Không có quy ước đặt tên khóa, vì vậy bạn có thể sử dụng chúng theo ý muốn.

Dựa trên các phím này, SharedResource.resx SharedResource.en.resx chúng ta sẽ SharedResource.es.resx điền vào văn bản được dịch.

SharedResource.resx

tên
Giá trị
Validate_Required {0} là một trường bắt buộc.
Validate_StringLength {0} có thể nhập tối đa {1} ký tự.
Validate_Alphanumeric {0} chỉ có thể nhập các ký tự chữ và số.
ID_DisplayName ID (nửa góc chữ và số)
Name_DisplayName Tên

SharedResource.en.resx

tên
Giá trị
Validate_Required "{0}" is a required input.
Validate_StringLength The maximum number of characters that can be entered in "{0}" is "{1}".
Validate_Alphanumeric Only alphanumeric characters can be entered for "{0}".
ID_DisplayName ID (alphanumeric characters)
Name_DisplayName Full name

SharedResource.es.resx

tên
Giá trị
Validate_Required "{0}" es una entrada obligatoria.
Validate_StringLength El número máximo de caracteres que se pueden ingresar en "{0}" es "{1}".
Validate_Alphanumeric Solo se pueden ingresar caracteres alfanuméricos para "{0}".
ID_DisplayName ID (caracteres alfanuméricos)
Name_DisplayName Nombre completo

Nhập thông báo lỗi xác minh thay thế tên tham số và số bằng {0} hoặc {1}, v.v. Tích cực sử dụng nó.

Đa ngôn ngữ được áp dụng cho điều hướng dữ liệu

Tất cả các cài đặt đa ngôn ngữ được áp dụng cho thuộc tính mô hình.

Để áp dụng cho tên hiển thị của tham Display số, đính kèm và Name chỉ định phím tài nguyên được chia sẻ.resx cho thuộc tính.

Để áp dụng cho thông báo lỗi xác minh đầu vào, chỉ ErrorMessage định phím SharedResource.resx cho mỗi thuộc tính xác minh.

public class UserViewModel
{
  [Required(ErrorMessage = "Validate_Required")]
  [Display(Name = "ID_DisplayName")]
  [StringLength(20, ErrorMessage = "Validate_StringLength")]
  [RegularExpression(@"^[0-9a-zA-Z]*$", ErrorMessage = "Validate_Alphanumeric")]
  public string ID { get; set; }

  [Display(Name = "Name_DisplayName")]
  [StringLength(50, ErrorMessage = "Validate_StringLength")]
  public string Name { get; set; }

  // 省略
}

Thiết lập hiện đã hoàn tất. Bây giờ, chúng ta hãy chạy nó và xem nó hoạt động như thế nào.

Nhân tiện, số ký tự đầu vào bị giới hạn bởi thuộc tính gắn thẻ đầu maxlength vào. Nếu bạn muốn xem thư, bạn cần phải loại bỏ các hạn chế, ví dụ: sử dụng công cụ dành cho nhà phát triển trình duyệt web.

Nhân tiện, khi bạn đăng ký trống như tuổi tác và ngày tháng, một số thông báo sẽ được hiển thị bằng tiếng Anh. Đây là thông báo được thiết lập ở phía khung và chúng tôi sẽ giải thích cách xử lý nhiều ngôn ngữ trong một gợi ý riêng biệt.

Giới thiệu về tất cả các mã

Lời nhắc này chỉ liệt kê một số thuộc tính nhất định, nhưng mã mẫu bao gồm tất cả các trường đầu vào tương ứng với HTML5. Nếu bạn muốn xác nhận, hãy xem liên kết đến trang trên.

Phát hành trong phần sau

UserViewModel.cs

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace LocalizationDataAnnotation.Models
{
  public class UserViewModel
  {
    [Required(ErrorMessage = "Validate_Required")]
    [Display(Name = "ID_DisplayName")]
    [StringLength(20, ErrorMessage = "Validate_StringLength")]
    [RegularExpression(@"^[0-9a-zA-Z]*$", ErrorMessage = "Validate_Alphanumeric")]
    public string ID { get; set; }

    [Display(Name = "Name_DisplayName")]
    [StringLength(50, ErrorMessage = "Validate_StringLength")]
    public string Name { get; set; }

    [Display(Name = "Password_DisplayName")]
    [StringLength(50, MinimumLength = 8, ErrorMessage = "Validate_StringLengthRange")]
    [DataType(DataType.Password)]
    [RegularExpression(@"^[0-9a-zA-Z]*$", ErrorMessage = "Validate_Alphanumeric")]
    public string Password { get; set; }

    [Display(Name = "ConfirmPassword_DisplayName")]
    [StringLength(50, MinimumLength = 8, ErrorMessage = "Validate_StringLengthRange")]
    [DataType(DataType.Password)]
    [Compare(nameof(Password), ErrorMessage = "Validate_Compare")]
    public string ConfirmPassword { get; set; }

    [Display(Name = "Email_DisplayName")]
    [EmailAddress(ErrorMessage = "Validate_EmailAddress")]
    [DataType(DataType.EmailAddress)] // スキャフォールディングするときはコメントアウトする
    public string Email { get; set; }

    [Display(Name = "Age_DisplayName")]
    [Required(ErrorMessage = "Validate_Required")]
    [Range(0, 150, ErrorMessage = "Validate_Range")]
    public int Age { get; set; }

    [Display(Name = "Gender_DisplayName")]
    [Required(ErrorMessage = "Validate_Required")]
    [EnumDataType(typeof(GenderType))]
    public GenderType Gender { get; set; }

    [Display(Name = "Birthday_DisplayName")]
    [DataType(DataType.Date)]
    public DateTime Birthday { get; set; }

    [Display(Name = "Phone_DisplayName")]
    [Phone(ErrorMessage = "Validate_Phone")]
    [DataType(DataType.PhoneNumber)] // スキャフォールディングするときはコメントアウトする
    public string Phone { get; set; }

    [Display(Name = "PostalCode_DisplayName")]
    [DataType(DataType.PostalCode)]
    public string PostalCode { get; set; }

    [Display(Name = "CreditCard_DisplayName")]
    [CreditCard(ErrorMessage = "Validate_CreditCard")]
    [DataType(DataType.CreditCard)] // スキャフォールディングするときはコメントアウトする
    public string CreditCard { get; set; }

    [Display(Name = "Money_DisplayName")]
    [DataType(DataType.Currency)]
    public decimal Money { get; set; }

    [Display(Name = "StartDateTime_DisplayName")]
    [DataType(DataType.DateTime)]
    public DateTime StartDateTime { get; set; }

    [Display(Name = "WakeUpTime_DisplayName")]
    [DataType(DataType.Time)]
    public TimeSpan WakeUpTime { get; set; }

    [Display(Name = "Homepage_DisplayName")]
    [Url(ErrorMessage = "Validate_Url")]
    [DataType(DataType.Url)] // スキャフォールディングするときはコメントアウトする
    public string Homepage { get; set; }

    [Display(Name = "MyImage_DisplayName")]
    [Url(ErrorMessage = "Validate_Url")]
    [DataType(DataType.ImageUrl)] // スキャフォールディングするときはコメントアウトする
    public string MyImage { get; set; }

    [Display(Name = "MyColor_DisplayName")]
    public string MyColor { get; set; }

    [Display(Name = "WorkingDays_DisplayName")]
    [MaxLength(5, ErrorMessage = "Validate_MaxLength")]
    [EnumDataType(typeof(DayOfWeek))]
    public DayOfWeek[] WorkingDays { get; set; }

    [Display(Name = "VacationDay_DisplayName")]
    [MinLength(3, ErrorMessage = "Validate_MinLength")]
    [EnumDataType(typeof(DayOfWeek))]
    public DayOfWeek[] VacationDay { get; set; }

    [Display(Name = "Comment_DisplayName")]
    [StringLength(200, ErrorMessage = "Validate_StringLength")]
    [DataType(DataType.MultilineText)]
    public string Comment { get; set; }

    [Display(Name = "FileName_DisplayName")]
    [FileExtensions(Extensions = "png", ErrorMessage = "Validate_FileExtensions")]
    public string FileName { get; set; }

    [Display(Name = "UploadFile_DisplayName")]
    [DataType(DataType.Upload)]
    public List<IFormFile> UploadFile { get; set; }

    [Display(Name = "Month_DisplayName")]
    public DateTime Month { get; set; }

    [Display(Name = "Search_DisplayName")]
    public string Search { get; set; }

    [Display(Name = "Range_DisplayName")]
    [Range(10, 100, ErrorMessage = "Validate_Range")]
    public int Range { get; set; }

    [Display(Name = "Week_DisplayName")]
    public string Week { get; set; }

    [Display(Name = "IsAccepted_DisplayName")]
    [Required(ErrorMessage = "Validate_Required")]
    public bool IsAccepted { get; set; }
  }

  public enum GenderType
  {
    None,
    Man,
    Woman,
    Other,
  }
}

HomeController.cs

using LocalizationDataAnnotation.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace LocalizationDataAnnotation.Controllers
{
  public class HomeController : Controller
  {
    private readonly ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
      _logger = logger;
    }

    public IActionResult Index()
    {
      return View();
    }

    public IActionResult Privacy()
    {
      return View();
    }

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
      return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }

    public IActionResult Create()
    {
      SetDayOfWeeksViewData();
      return View();
    }

    [HttpPost]
    public IActionResult Create(UserViewModel model)
    {
      SetDayOfWeeksViewData();

      // エラーなら差し戻し
      if (ModelState.IsValid == false) return View(model);

      // 正常に登録できた場合は Index に戻る
      return RedirectToAction(nameof(Index));
    }

    /// <summary>曜日の一覧を ViewData に設定します。</summary>
    private void SetDayOfWeeksViewData()
      => ViewData["DayOfWeeks"] = ((DayOfWeek[])Enum.GetValues(typeof(DayOfWeek))).Select(x => new SelectListItem(x.ToString(), ((int)x).ToString()));
  }
}

Create.cshtml

@model LocalizationDataAnnotation.Models.UserViewModel
@using System.Globalization;
@{
  ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>UserViewModel</h4>
<hr />
<div class="row">
  <div class="col-md-4">
    <form asp-action="Create" enctype="multipart/form-data" >
      <div asp-validation-summary="ModelOnly" class="text-danger"></div>
      <div class="form-group">
        <label asp-for="ID" class="control-label"></label>
        <input asp-for="ID" class="form-control" />
        <span asp-validation-for="ID" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Name" class="control-label"></label>
        <input asp-for="Name" class="form-control" />
        <span asp-validation-for="Name" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Password" class="control-label"></label>
        <input asp-for="Password" class="form-control" />
        <span asp-validation-for="Password" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="ConfirmPassword" class="control-label"></label>
        <input asp-for="ConfirmPassword" class="form-control" />
        <span asp-validation-for="ConfirmPassword" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Email" class="control-label"></label>
        <input asp-for="Email" class="form-control" />
        <span asp-validation-for="Email" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Age" class="control-label"></label>
        <input asp-for="Age" class="form-control" />
        <span asp-validation-for="Age" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Gender"></label>
        <div>
          <label><input type="radio" asp-for="Gender" value="@(GenderType.None)" />@(GenderType.None)</label>
          <label><input type="radio" asp-for="Gender" value="@(GenderType.Man)" />@(GenderType.Man)</label>
          <label><input type="radio" asp-for="Gender" value="@(GenderType.Woman)" />@(GenderType.Woman)</label>
        </div>
        <span asp-validation-for="Gender" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Birthday" class="control-label"></label>
        <input asp-for="Birthday" class="form-control" />
        <span asp-validation-for="Birthday" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Phone" class="control-label"></label>
        <input asp-for="Phone" class="form-control" />
        <span asp-validation-for="Phone" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="PostalCode" class="control-label"></label>
        <input asp-for="PostalCode" class="form-control" />
        <span asp-validation-for="PostalCode" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="CreditCard" class="control-label"></label>
        <input asp-for="CreditCard" class="form-control" />
        <span asp-validation-for="CreditCard" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Money" class="control-label"></label>
        <input asp-for="Money" class="form-control" />
        <span asp-validation-for="Money" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="StartDateTime" class="control-label"></label>
        <input asp-for="StartDateTime" class="form-control" />
        <span asp-validation-for="StartDateTime" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="WakeUpTime" class="control-label"></label>
        <input asp-for="WakeUpTime" class="form-control" />
        <span asp-validation-for="WakeUpTime" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Homepage" class="control-label"></label>
        <input asp-for="Homepage" class="form-control" />
        <span asp-validation-for="Homepage" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="MyImage" class="control-label"></label>
        <input asp-for="MyImage" class="form-control" />
        <span asp-validation-for="MyImage" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="MyColor" class="control-label"></label>
        <input asp-for="MyColor" class="form-control" type="color" />
        <span asp-validation-for="MyColor" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="WorkingDays" class="control-label"></label>
        <select asp-for="WorkingDays" class="form-control" asp-items="@((IEnumerable<SelectListItem>)ViewData["DayOfWeeks"])" multiple></select>
        <span asp-validation-for="WorkingDays" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="VacationDay" class="control-label"></label>
        <select asp-for="VacationDay" class="form-control" asp-items="@((IEnumerable<SelectListItem>)ViewData["DayOfWeeks"])" multiple></select>
        <span asp-validation-for="VacationDay" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Comment" class="control-label"></label>
        <textarea asp-for="Comment" class="form-control"></textarea>
        <span asp-validation-for="Comment" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="FileName" class="control-label"></label>
        <input asp-for="FileName" class="form-control" />
        <span asp-validation-for="FileName" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="UploadFile" class="control-label"></label>
        <input asp-for="UploadFile" type="file" multiple />
        <span asp-validation-for="UploadFile" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Month" class="control-label"></label>
        <input asp-for="Month" class="form-control" type="month" />
        <span asp-validation-for="Month" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Search" class="control-label"></label>
        <input asp-for="Search" class="form-control" type="search" />
        <span asp-validation-for="Search" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Range" class="control-label"></label>
        <input asp-for="Range" class="form-control" type="range" min="10" max="100" />
        <span asp-validation-for="Range" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Week" class="control-label"></label>
        <input asp-for="Week" class="form-control" type="week" />
        <span asp-validation-for="Week" class="text-danger"></span>
      </div>
      <div class="form-group form-check">
        <label class="form-check-label">
          <input class="form-check-input" asp-for="IsAccepted" /> @Html.DisplayNameFor(model => model.IsAccepted)
        </label>
      </div>
      <div class="form-group">
        <input type="submit" value="Create" class="btn btn-primary" asp-route-culture="@CultureInfo.CurrentCulture.Name" />
      </div>
    </form>
  </div>
</div>

<div>
  <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
  @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}