תמיכה רב-לשונית עבור DataAnnotations המשמשת עבור שמות פרמטרים, הודעות אימות קלט וכו '.
סביבה
- ליבה ASP.NET
-
- 5.0 MVC
הנחת יסוד
טיפים אלה נכתבים כהבנת העצות הבאות:
כמו כן, אם אתה יוצר פרוייקט חדש, עליך להוסיף את הקבצים והקוד הבאים בהתבסס על עצות לעיל.
- צור קובץ SharedResource.resx (+en, es). (ייתכן שהתוכן ריק).
- יצירת קובץ מקור משותף.cs
- הוסף קוד לוקליזציה לאתחול.קביעת תצורה שלServices
- הוסף קוד לוקליזציה לאתחול.קבע תצורה
תיקוני .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));
});
}
מידול עבור קלט
צור מודל לאגד למסך הקלט. במדגם זה, יצרנו מספר מאפיינים כדי להתאים פקדי קלט שונים. אם אתה מתקשה ליצור, באפשרותך פשוט ליצור שניים.
צור .cs של UserViewModel בתיקיה מודלים.
הקוד צריך להיראות כך: טווח השמות צריך להיות מתאים. התכונות שהגדרת אינן רלוונטיות במיוחד לשפות מרובות מכיוון שהן מוקצות להן בלבד. תמיכה רב לשונית תיעשה מאוחר יותר.
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));
}
}
}
קישור למסך רישום משתמש
צור קישור למסך רישום המשתמש בתצוגות\בית\אינדקס.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
לחץ באמצעות לחצן העכבר הימני על הפעולה ובחר הוסף תצוגה.
בחר תצוגת תער.
הפוך את התבנית "צור" ואת מחלקת המודל "UserViewModel".
אם אתה משתמש UserViewModel
בקוד לדוגמה, כללתי גם הערות בקוד.
אם תציב תכונות מסוימות במאפיין, תקבל שגיאה בעת יצירת קוד בפיגומים.
נא הגיב באופן זמני לפני יצירת תצוגה.
אם אתה באמת מקבל שגיאה בעת יצירתה, צור תצוגת Razor ריקה וכלול את הקוד הבא:
@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 completo |
הודעות שגיאה של אימות קלט מחליפות שמות פרמטרים ומספרים {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. אם ברצונך לבדוק, עיין בקישור מעל הדף.
מופיע בחלק שלהלן
משתמשViewדוג.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,
}
}
"הום קונטרולר.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");}
}