Večjezična podpora za DataAnnotations, ki se uporablja za imena parametrov, sporočila za preverjanje veljavnosti vnosa itd.
okolje
- ASP.NET Core
-
- 5.0 MVC
Predpostavki
Ti nasveti so napisani kot razumevanje naslednjih nasvetov:
Če ustvarjate nov projekt, morate na podlagi zgornjih nasvetov dodati naslednje datoteke in kodo.
- Ustvarite datoteko SharedResource.resx (+sl, es). (Vsebina je lahko prazna.)
- Ustvarjanje datoteke v skupni rabi.cs datoteke
- Dodajanje kode lokalizacije zagonu.ConfigureServices
- Dodajte kodo za lokalizacijo v zagon.Konfiguriraj
Popravki .cs zagona
Ker so potrebne dodatne večjezične nastavitve, povezane z DataAnnotations, spremenite metodo na Startup.ConfigureServices
naslednji način:
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));
});
}
Modeliranje za vnos
Ustvarite model, ki se bo priklopio na vhodni zaslon. V tem vzorcu smo ustvarili številne lastnosti za namestitev različnih vhodnih kontrolnikov. Če imate težave pri ustvarjanju, lahko ustvarite le dve.
Ustvarite userViewModel .cs v mapi Modeli.
Koda bi morala izgledati takole: Imenski prostor mora biti primeren. Atributi, ki ste jih nastavili, niso zelo pomembni za več jezikov, ker so jim dodeljeni le. Večjezična podpora bo opravljena kasneje.
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; }
// 省略
}
// 省略
}
Ustvarjanje dejanja
Ustvarite dejanja za prikaz uporabnikovega zaslona za registracijo in izvajanje HomeController
registracijskih dejanj.
Ustvarjanje zaslonov in dejanj ni glavna tema teh nasvetov, zato je primerno. Poleg tega dejanski postopek registracije ni izveden.
// 初期コードは省略
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));
}
}
}
Povezava do zaslona za registracijo uporabnika
Ustvarite povezavo do zaslona za registracijo uporabnika v views\Home\Index.cshtml. Vse lahko napišete, dokler imate prehod zaslona.
asp-route-culture
Atribut odpre stran v določenem jeziku.
<!-- 初期コード省略 -->
<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>
Ustvarjanje zaslona za registracijo uporabnika
Create
Z desno tipko miške kliknite dejanje in izberite Dodaj pogled.
Izberite Pogled britvic.
Naredite predlogo »Ustvari« in razred modela »UserViewModel«.
Če uporabljate vzorčno kodo, sem v kodo vključil tudi UserViewModel
komentarje.
Če postavite določene atribute v lastnost, boste pri generiranju kode pri odrih dobili napako.
Preden ustvarite pogled, začasno komentirajte.
Če pri ustvarjanju res pride do napake, ustvarite prazen pogled Razor in vključite naslednjo kodo:
@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");}
}
Za zdaj lahko kot pripravljalno fazo do zdaj uspešno zgradite kodo in poskusite videti in pravilno zagnati zaslon.
Večjezična registracija besedila za DataAnnotations
Vse nepremičnine so dolgo za pojasniti, tako da bomo govorili ID
z in za . Name
Druge lastnosti so večjezične na podoben način, zato jih preizkusite.
Naslednja besedila so na voljo v več jezikih tukaj.
Večjezične besedilne | tipke |
---|---|
Prikazano ime parametra ID | ID_DisplayName |
Sporočilo o napaki, ko ID ni vnesen | Validate_Required |
Sporočilo o napaki, ko vhodni znak ID presega 20 znakov | Validate_StringLength |
Sporočilo o napaki pri vnašanju ID-ja z neštevilčnimi znaki | Validate_Alphanumeric |
Prikazano ime parametra imena | Name_DisplayName |
Sporočilo o napaki, ko je vneseno več kot 50 znakov | Validate_StringLength |
Validate_XXXXX
univerzalna. Ni konvencije o imenovanju ključev, zato jo lahko prosto priložite.
S temi ključi kot osnovo bomo prevedeno besedilo izpolnili v SharedResource.resx
SharedResource.en.resx
, , SharedResource.es.resx
.
Skupna raboResource.resx
Vrednostimena | |
---|---|
Validate_Required | "{0}" je potrebno. |
Validate_StringLength | V »{1}« lahko vnesete do »{0}«. |
Validate_Alphanumeric | {0} je lahko samo alfanumerično. |
ID_DisplayName | ID (alfanumerično) |
Name_DisplayName | identiteta |
SharedResource.sl.resx
Vrednostimena | |
---|---|
Validate_Required | "{0}" je zahtevan vhod. |
Validate_StringLength | Največje število znakov, ki jih je mogoče vnesti v »{0}« je »{1}«. |
Validate_Alphanumeric | Za »{0}« lahko vnesete le alfanumerične znake. |
ID_DisplayName | ID (alfanumerični znaki) |
Name_DisplayName | Polno ime |
SharedResource.es.resx
Vrednostimena | |
---|---|
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 (karakteres alfanuméricos) |
Name_DisplayName | Nombre completo |
Sporočila o napakah pri preverjanju vnosa nadomestijo imena parametrov in številke z {0} in {1}. Uporabimo ga pozitivno.
Večjezična uporaba za DataAnnotations
Vse večjezične nastavitve se uporabljajo za atribute modela (DataAnnotations).
Če ga želite uporabiti za prikazano ime parametra, v lastnosti priložite in določite ključ v skupni Display
Name
rabiResource.resx.
Če želite uporabiti sporočila o napakah med preverjanjem veljavnosti vnosa, v lastnosti vsakega atributa preverjanja veljavnosti določite ključ v skupni ErrorMessage
rabiResource.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; }
// 省略
}
S tem se dokonča nastavitev. Po tem ga zaženite, da vidite, kako deluje.
Mimogrede, število vhodnih znakov je omejeno z atributom vhodne maxlength
oznake.
Če želite videti sporočilo, morate odstraniti omejitve, na primer v orodjih razvijalcev spletnega brskalnika.
Mimogrede, pri registraciji vaše starosti, datuma itd. so prikazana nekatera sporočila prazna. To je sporočilo, ki je nastavljeno na okvirni strani, drugi nasveti pa vam bodo pokazali, kako ga podpreti v več jezikih.
Za vse kode
Ta Namigi vsebujejo le nekatere lastnosti, vendar vzorčna koda zajema vsa vhodna polja, ki jih omogoča HTML5. Če želite preveriti, si oglejte povezavo nad stranjo.
V nadaljevanju naveden del
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()));
}
}
Ustvari.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");}
}