Daugiakalbis "DataAnnotations", naudojamo parametrų pavadinimams, įvesties tikrinimo pranešimams ir kt., palaikymas.
Aplinkos
- ASP.NET branduolys
-
- 5,0 MVC
Prielaida
Šie patarimai yra parašyta kaip suprasti šiuos patarimus:
Be to, jei kuriate naują projektą, turite pridėti šiuos failus ir kodą pagal anksčiau pateiktus patarimus.
- Sukurkite SharedResource.resx (+en, es) failą. (Turinys gali būti tuščias.)
- SharedResource.cs failo kūrimas
- Įtraukti lokalizacijos kodą į Startup.ConfigureServices
- Įtraukti lokalizacijos kodą į Startup.Configure
Paleisties .cs pataisos
Kadangi reikia papildomų daugiakalbių parametrų, susijusių su DataAnnotations, Startup.ConfigureServices
modifikuokite metodą taip:
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));
});
}
Įvesties modeliavimas
Sukurkite modelį, kuris būtų susietas su įvesties ekranu. Šiame pavyzdyje sukūrėme keletą ypatybių, kad tilptų įvairūs įvesties valdikliai. Jei kyla problemų kuriant, galite tiesiog sukurti du.
Aplanke Modeliai sukurkite "UserViewModel" .cs.
Kodas turėtų atrodyti taip: Vardų sritis turėtų būti tinkama. Jūsų nustatyti atributai nėra labai svarbūs kelioms kalboms, nes jie priskiriami tik jiems. Daugiakalbė parama bus teikiama vėliau.
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; }
// 省略
}
// 省略
}
Veiksmo kūrimas
Sukurkite veiksmus, kad būtų rodomas vartotojo registracijos ekranas, ir atlikite registracijos HomeController
veiksmus.
Ekranų ir veiksmų kūrimas nėra pagrindinė šių patarimų tema, todėl tikslinga. Be to, faktinis registracijos procesas neatliekamas.
// 初期コードは省略
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));
}
}
}
Vartotojo registracijos ekrano saitas
Sukurkite saitą su vartotojo registracijos ekranu dalyje Views\Home\Index.cshtml. Galite rašyti bet ką tol, kol galite turėti ekrano perėjimą.
asp-route-culture
Atributas atidaro puslapį nurodyta kalba.
<!-- 初期コード省略 -->
<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>
Vartotojo registracijos ekrano kūrimas
Create
Dešiniuoju pelės mygtuku spustelėkite veiksmą ir pasirinkite Įtraukti rodinį.
Pasirinkite Skustuvo rodinys.
Padarykite šabloną "Sukurti" ir modelio klasę "UserViewModel".
Jei naudojate UserViewModel
kodo pavyzdį, į kodą taip pat įtraukiau komentarus.
Jei į ypatybę įdėsite tam tikrų atributų, sugeneruodami kodą pastoliuose gausite klaidą.
Prieš kurdami rodinį, laikinai komentuokite.
Jei kurdami tikrai gaunate klaidą, sukurkite tuščią skustuvo rodinį ir įtraukite šį kodą:
@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");}
}
Dabar, kaip parengiamasis etapas, galite sukurti kodą iki šiol sėkmingai, ir pabandyti pamatyti ir paleisti ekraną teisingai.
Daugiakalbė teksto registracija DataAnnotations
Visos savybės yra ilgai paaiškinti, todėl mes ID
pasikalbėti ir už . Name
Kitos savybės yra daugiakalbės panašiu būdu, todėl išbandykite juos.
Šiuos tekstus galima rasti keliomis kalbomis čia.
Daugiakalbiai teksto | klavišai |
---|---|
Id parametro rodomas pavadinimas | ID_DisplayName |
Klaidos pranešimas, kai ID neįvestas | Validate_Required |
Klaidos pranešimas, kai ID įvesties simbolis viršija 20 simbolių | Validate_StringLength |
Klaidos pranešimas, kai ID įvedamas su ne skaitiniais simboliais | Validate_Alphanumeric |
Rodomas pavadinimo parametro pavadinimas | Name_DisplayName |
Klaidos pranešimas, kai pavadinime yra daugiau nei 50 simbolių | Validate_StringLength |
Validate_XXXXX
būti universalūs. Nėra pagrindinės pavadinimų suteikimo konvencijos, todėl galite ją laisvai pridėti.
Naudodami šiuos raktus kaip pagrindą, SharedResource.resx
mes užpildysime SharedResource.en.resx
išverstą tekstą į , SharedResource.es.resx
, .
SharedResource.resx
Pavadinimo | reikšmė |
---|---|
Validate_Required | Reikalingas "{0}". |
Validate_StringLength | "{0}" galite įvesti iki "{1}". |
Validate_Alphanumeric | {0} gali būti tik raidinis-skaitinis. |
ID_DisplayName | ID (raidinis-skaitinis) |
Name_DisplayName | Tapatybės |
SharedResource.en.resx
Pavadinimo | reikšmė |
---|---|
Validate_Required | "{0}" yra būtina įvestis. |
Validate_StringLength | Maksimalus simbolių, kuriuos galima įvesti į "{0}", skaičius yra "{1}". |
Validate_Alphanumeric | "{0}" galima įvesti tik raidinius ir skaitinius simbolius. |
ID_DisplayName | ID (raidiniai ir skaitiniai simboliai) |
Name_DisplayName | Vardas ir pavardė |
SharedResource.es.resx
Pavadinimo | reikšmė |
---|---|
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 karakasas alfanuméricos para "{0}". |
ID_DisplayName | ID (karakasai alfanuméricos) |
Name_DisplayName | Nombre kompletas |
Įvesties tikrinimo klaidų pranešimai pakeičia parametrų pavadinimus ir skaičius {0} ir {1}. Panaudokime jį teigiamai.
Daugiakalbis taikymas DataAnnotations
Visi daugiakalbiai parametrai taikomi modelio atributams (DataAnnotations).
Norėdami jį taikyti rodomam parametro pavadinimui, Display
ypatybėje pridėkite ir nurodykite Name
failą sharedResource.resx raktą.
Norėdami taikyti klaidų pranešimams tikrinant įvestį, ErrorMessage
nurodykite sharedResource.resx raktą kiekvieno tikrinimo atributo ypatybėje.
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; }
// 省略
}
Tai užbaigia sąranką. Po to paleiskite jį, kad pamatytumėte, kaip tai veikia.
Beje, įvesties simbolių skaičių riboja įvesties maxlength
žymės atributas.
Jei norite matyti pranešimą, turite pašalinti apribojimus, pvz., žiniatinklio naršyklės kūrėjo įrankiuose.
Beje, yra keletas pranešimų rodomi registruojant savo amžių, datą ir tt tuščias. Tai pranešimas, nustatytas sistemos pusėje, tačiau kitame patarime bus parodyta, kaip jį palaikyti keliomis kalbomis.
Visiems kodams
Šiuose patarimuose yra tik keletas ypatybių, tačiau kodo pavyzdys apima visus html5 palaikančius įvesties laukus. Jei norite patikrinti, prašome kreiptis į virš puslapio esančią nuorodą.
Išvardyti iš dalies žemiau
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");}
}