پشتیبانی چند زبانه از DataAnnotations مورد استفاده برای نام پارامترها، پیام های اعتبارسنجی ورودی، و غیره.
محیط
- ASP.NET هسته
-
- 5.0 MVC
فرض
این نکات به عنوان درک نکات زیر نوشته شده است:
همچنین اگر در حال ایجاد یک پروژه جدید هستید، باید فایل ها و کدهای زیر را بر اساس راهنمایی های بالا اضافه کرده باشد.
- ایجاد یک فایل SharedResource.resx (+en, es) . (محتویات ممکن است خالی باشد.)
- ایجاد یک فایل مشترکResource.cs است
- افزودن کد محلی سازی به Startup.ConfigureServices
- افزودن کد محلی سازی به Startup.Configure
راه اندازی .cs رفع
از آنجا که تنظیمات چند زبانه اضافی مربوط به DataAnnotations مورد نیاز است، روش Startup.ConfigureServices
را به صورت زیر تغییر دهید:
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));
});
}
مدل سازی برای ورودی
یک مدل برای اتصال به صفحه ورودی ایجاد کنید. در این نمونه تعدادی از خواص را ایجاد کرده ایم تا کنترل های ورودی مختلف را در خود جای دهیم. اگر شما با مشکل ایجاد، شما فقط می توانید دو ایجاد کنید.
ایجاد یک مدل UserViewmodel .cs پوشه مدل ها.
کد باید این شکلی باشد: فضای نام باید مناسب باشد. ویژگی هایی که شما تنظیم می کنید خیلی به زبان های متعدد مربوط نمی شوند زیرا فقط به آن ها اختصاص داده می شوند. پشتیبانی چند زبانه بعداً انجام خواهد شد.
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; }
// 省略
}
// 省略
}
ایجاد یک عمل
ایجاد اقدامات در برای نمایش صفحه نمایش ثبت نام کاربر و انجام اقدامات HomeController
ثبت نام.
ایجاد صفحه نمایش و اقدامات موضوع اصلی این نکته نیست، بنابراین مناسب است. علاوه بر این، فرایند ثبت نام واقعی انجام نمی شود.
// 初期コードは省略
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));
}
}
}
لینک به صفحه ثبت نام کاربر
ایجاد یک لینک به صفحه ثبت نام کاربر در نمایش صفحه اصلی \Index.cshtml. شما می توانید هر چیزی را بنویسید تا زمانی که شما می توانید انتقال صفحه نمایش داشته باشد.
asp-route-culture
ویژگی صفحه را در زبان مشخص شده باز می کند.
<!-- 初期コード省略 -->
<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>
ایجاد صفحه ثبت نام کاربر
Create
روی عمل کلیک راست کنید و Add View را انتخاب کنید.
مشاهده تیغ را انتخاب کنید.
قالب "ایجاد" و کلاس مدل "UserViewModel" را.
اگر از کد نمونه استفاده می کنید، من هم UserViewModel
نظراتی را در کد گنجانده ام.
اگر ویژگی های خاصی را در یک ملک قرار داده باشد، هنگام تولید کد در داربست خطا دریافت خواهید کرد.
لطفا قبل از ایجاد یک نمایش به طور موقت اظهار نظر کنید.
اگر شما واقعا خطا زمانی که شما آن را ایجاد کنید, ایجاد یک نمایش تیغ خالی و شامل کد زیر:
@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");}
}
در حال حاضر، به عنوان یک مرحله مقدماتی، شما می توانید کد را تا کنون با موفقیت بسازید، و سعی کنید صفحه نمایش را به درستی ببینید و اجرا کنید.
ثبت متن چند زبانه برای DataAnnotations
همه خواص طولانی برای توضیح ، بنابراین ما با و ID
برای صحبت کنید. Name
خواص دیگر چند زبانه در راه مشابه هستند، بنابراین آنها را امتحان کنید.
متن های زیر به زبان های متعدد در اینجا موجود هستند.
کلیدهایمتنی چند زبانه | |
---|---|
نام نمایش پارامتر شناسه | ID_DisplayName |
پیام خطا هنگامی که شناسه وارد نشده است | Validate_Required |
پیام خطا هنگامی که شناسه کاراکتر ورودی بیش از 20 کاراکتر | Validate_StringLength |
پیام خطا هنگامی که شناسه با کاراکترهای غیر شماره ای تایپ می شود | Validate_Alphanumeric |
نام نام پارامتر نام نمایش | Name_DisplayName |
پیام خطا هنگامی که نام بیش از 50 کاراکتر وارد شده است | Validate_StringLength |
Validate_XXXXX
جهانی باشد. هیچ کنوانسیون نام گذاری کلیدی وجود ندارد، بنابراین شما می توانید آزادانه آن را ضمیمه کنید.
با استفاده از این کلیدها به عنوان اساس ، ما در متن ترجمه SharedResource.resx
شده را پر کنید ، ، SharedResource.en.resx
SharedResource.es.resx
.
SharedResource.resx
مقدارنام | |
---|---|
Validate_Required | "{0}" مورد نیاز است. |
Validate_StringLength | شما می توانید وارد کنید تا "{1}" در "{0}". |
Validate_Alphanumeric | {0} فقط می تواند عددی آلفا باشد. |
ID_DisplayName | شناسه (عددی آلفا) |
Name_DisplayName | هویت |
SharedResource.en.resx
مقدارنام | |
---|---|
Validate_Required | "{0}" یک ورودی مورد نیاز است. |
Validate_StringLength | بیش ترین تعداد کاراکتری که می تواند در "{0}" وارد شود "{1}" است. |
Validate_Alphanumeric | فقط کاراکترهای عددی آلفا را می توان برای "{0}". |
ID_DisplayName | شناسه (کاراکترهای عددی آلفا) |
Name_DisplayName | نام کامل |
SharedResource.es.resx
مقدارنام | |
---|---|
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 completeo |
پیام های خطای اعتبارسنجی ورودی جایگزین نام پارامترها و اعداد با {0} و {1}. بیایید از آن به طور مثبت استفاده کنیم.
کاربرد چند زبانه به DataAnnotations
تمام تنظیمات چند زبانه به ویژگی های مدل (DataAnnotations) اعمال می شوند.
برای اعمال آن به نام نمایش پارامتر، یک کلید Display
Name
sharedResource.resx را در ملک ضمیمه و مشخص کنید.
برای اعمال پیام های خطا در طول اعتبارسنجی ورودی، یک کلید ErrorMessage
sharedResource.resx را در ویژگی هر ویژگی اعتبارسنجی مشخص کنید.
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; }
// 省略
}
این کار راه اندازی را کامل می کند. بعد از اون، اجراش کن تا ببيني چطور يجوري کار ميکنه.
به هر حال تعداد کاراکترهای ورودی با ویژگی تگ ورودی محدود می maxlength
شود.
اگر می خواهید پیام را ببینید، باید محدودیت ها را مانند ابزارهای توسعه دهنده مرورگر وب خود حذف کنید.
به هر حال، برخی از پیام های نمایش داده شده در هنگام ثبت سن، تاریخ و غیره خالی وجود دارد. این یک پیام است که در سمت چارچوب راه اندازی شده است، اما نکات دیگری به شما نشان خواهد داد که چگونه آن را به زبان های متعدد پشتیبانی کنید.
برای همه کدها
این نکته تنها شامل برخی خواص است، اما کد نمونه تمام فیلدهای ورودی با قابلیت html5 را پوشش می دهد. اگر می خواهید بررسی کنید، لطفا به لینک بالای صفحه مراجعه کنید.
ذکر شده در بخشی از زیر
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");}
}