如何在 Blazor 服务器端本地化验证消息 (DataAnnotationsValidator)
How to Localize validation message (DataAnnotationsValidator) in blazor server side
我在最新版本的 VS 2019 中使用 blazor 3.1。
到目前为止,我能够本地化页面标签(标题、table 字段等)。
在 ListEmployee.razor
页面上,我可以本地化 table 标题等。在 AddEmplyeeValidation.razor
页面上,我可以本地化表单标签,但在本地化验证消息。
对于 Employee.cs
文件的验证消息,验证消息在文件 Data.Employee.resx
和 Data.Employee.ar.resx
的 Resources/Data
文件夹中定义,但这似乎不起作用.
using System.ComponentModel.DataAnnotations;
namespace BlazorSPA1.Data
{
public class Employee
{
[MaxLength(50)]
public string Id { get; set; }
[Required (ErrorMessage ="Name is RRRequired")]
[StringLength(20, ErrorMessage = "Name is too long.")]
public string Name { get; set; }
[Required]
[StringLength(20)]
public string Department { get; set; }
[MaxLength(100)]
public string Designation { get; set; }
[MaxLength(100)]
public string Company { get; set; }
[MaxLength(100)]
public string City { get; set; }
}
}
如何根据 AddEmployeForm
的语言从资源文件加载验证消息?
@page "/addemployeeValidation"
@inject NavigationManager NavigationManager
@inject IEmployeeService EmployeeService
@inject IStringLocalizer<AddEmployeeValidation> L
<h2>Create Employee</h2>
<hr />
<EditForm Model="@employee" OnValidSubmit="@CreateEmployee">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label for="Name" class="control-label">@L["Name"]</label>
<input for="Name" class="form-control" @bind="@employee.Name" />
<ValidationMessage For="@(()=> employee.Name)" />
</div>
<div class="form-group">
<label for="Department" class="control-label">@L["Department"]</label>
<input for="Department" class="form-control" @bind="@employee.Department" />
</div>
<div class="form-group">
<label for="Designation" class="control-label">@L["Designation"]</label>
<input for="Designation" class="form-control" @bind="@employee.Designation" />
</div>
<div class="form-group">
<label for="Company" class="control-label">@L["Company"]</label>
<input for="Company" class="form-control" @bind="@employee.Company" />
</div>
<div class="form-group">
<label for="City" class="control-label">@L["City"]</label>
<input for="City" class="form-control" @bind="@employee.City" />
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Save" />
<input type="button" class="btn" @onclick="@Cancel" value="Cancel" />
</div>
</div>
</div>
</EditForm>
@code {
Employee employee = new Employee();
protected async Task CreateEmployee()
{
await EmployeeService.CreateEmployee(employee);
NavigationManager.NavigateTo("listemployees");
}
void Cancel()
{
NavigationManager.NavigateTo("listemployees");
}
}
我已经阅读了几篇文章并尝试了一些方法,但似乎没有任何效果。
这是我的 Startup.cs
代码:
services.AddServerSideBlazor(options => options.DetailedErrors = true);
services.AddLocalization(options => options.ResourcesPath = "Resources");
var supportedCultures = new List<CultureInfo> { new CultureInfo("en"), new CultureInfo("ar") };
services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("en");
options.SupportedUICultures = supportedCultures;
});
我正在使用以下示例进行本地化,但它没有显示如何本地化错误消息:
https://www.c-sharpcorner.com/article/localization-in-blazor-server/
文件夹结构图片供参考:
英文版的资源文件示例,我也有阿拉伯文文件:
在下面的屏幕截图中,您会看到正在从资源文件中正确提取字段名称,但验证消息不起作用并且仅以英文显示。
这是我的本地化数据注释错误消息的解决方案。我创建了两个资源文件,一个用于字段,另一个用于错误消息。
DisplayNameResource
用于本地化字段
ErrorMessageResource
用于本地化错误消息
在视图模型中 class 使用 Display
属性来本地化字段名称。要指定资源文件,请在 Display
属性上使用 ResourceType
属性:
[Display(Name = "Address", ResourceType = typeof(DisplayNameResource))]
并且在验证属性上使用ErrorMessageResourceName
和ErrorMessageResourceType
来指定资源文件:
[Required(ErrorMessageResourceName = "RequiredError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
这是完整的例子:
public class SomeViewModel
{
[Display(Name = "Address", ResourceType = typeof(DisplayNameResource))]
[Required(ErrorMessageResourceName = "RequiredError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
[StringLength(256, ErrorMessageResourceName = "MaxLengthError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
public string Address { get; set; }
[Display(Name = "Phone", ResourceType = typeof(DisplayNameResource))]
[Required(ErrorMessageResourceName = "RequiredError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
[RegularExpression("^09([0-9]{9})$", ErrorMessageResourceName = "PhoneLengthError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
public string Phone { get; set; }
[Display(Name = "Password", ResourceType = typeof(DisplayNameResource))]
[Required(ErrorMessageResourceName = "RequiredError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
[StringLength(50, MinimumLength = 6, ErrorMessageResourceType = typeof(ErrorMessageResource), ErrorMessageResourceName = "MinxMaxLengthError")]
public string Password { get; set; }
[Display(Name = "ConfirmPassword", ResourceType = typeof(DisplayNameResource))]
[Required(ErrorMessageResourceName = "RequiredError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
[StringLength(50, MinimumLength = 6, ErrorMessageResourceType = typeof(ErrorMessageResource), ErrorMessageResourceName = "MinxMaxLengthError")]
[Compare("Password", ErrorMessageResourceName = "PasswordConfirmMisMatch", ErrorMessageResourceType = typeof(ErrorMessageResource))]
public string ConfirmPassword { get; set; }
}
MaxLengthError
的错误消息是 {0} cannot be longer than {1} character
,因此 {0}
将替换为本地化的文件名,{1}
将替换为您的 256
在属性 [StringLength(256,...
上指定
之前有人问过这个问题:
我建议使用 FluentValidation 是更好的方法。这是我的 Github 存储库的 link,演示了它是如何工作的:
我没试过!
在 asp.net 核心的官方文档中有如何本地化的部分 DataAnnotations
也许你会发现一些 clues there.
我在最新版本的 VS 2019 中使用 blazor 3.1。
到目前为止,我能够本地化页面标签(标题、table 字段等)。
在 ListEmployee.razor
页面上,我可以本地化 table 标题等。在 AddEmplyeeValidation.razor
页面上,我可以本地化表单标签,但在本地化验证消息。
对于 Employee.cs
文件的验证消息,验证消息在文件 Data.Employee.resx
和 Data.Employee.ar.resx
的 Resources/Data
文件夹中定义,但这似乎不起作用.
using System.ComponentModel.DataAnnotations;
namespace BlazorSPA1.Data
{
public class Employee
{
[MaxLength(50)]
public string Id { get; set; }
[Required (ErrorMessage ="Name is RRRequired")]
[StringLength(20, ErrorMessage = "Name is too long.")]
public string Name { get; set; }
[Required]
[StringLength(20)]
public string Department { get; set; }
[MaxLength(100)]
public string Designation { get; set; }
[MaxLength(100)]
public string Company { get; set; }
[MaxLength(100)]
public string City { get; set; }
}
}
如何根据 AddEmployeForm
的语言从资源文件加载验证消息?
@page "/addemployeeValidation"
@inject NavigationManager NavigationManager
@inject IEmployeeService EmployeeService
@inject IStringLocalizer<AddEmployeeValidation> L
<h2>Create Employee</h2>
<hr />
<EditForm Model="@employee" OnValidSubmit="@CreateEmployee">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label for="Name" class="control-label">@L["Name"]</label>
<input for="Name" class="form-control" @bind="@employee.Name" />
<ValidationMessage For="@(()=> employee.Name)" />
</div>
<div class="form-group">
<label for="Department" class="control-label">@L["Department"]</label>
<input for="Department" class="form-control" @bind="@employee.Department" />
</div>
<div class="form-group">
<label for="Designation" class="control-label">@L["Designation"]</label>
<input for="Designation" class="form-control" @bind="@employee.Designation" />
</div>
<div class="form-group">
<label for="Company" class="control-label">@L["Company"]</label>
<input for="Company" class="form-control" @bind="@employee.Company" />
</div>
<div class="form-group">
<label for="City" class="control-label">@L["City"]</label>
<input for="City" class="form-control" @bind="@employee.City" />
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Save" />
<input type="button" class="btn" @onclick="@Cancel" value="Cancel" />
</div>
</div>
</div>
</EditForm>
@code {
Employee employee = new Employee();
protected async Task CreateEmployee()
{
await EmployeeService.CreateEmployee(employee);
NavigationManager.NavigateTo("listemployees");
}
void Cancel()
{
NavigationManager.NavigateTo("listemployees");
}
}
我已经阅读了几篇文章并尝试了一些方法,但似乎没有任何效果。
这是我的 Startup.cs
代码:
services.AddServerSideBlazor(options => options.DetailedErrors = true);
services.AddLocalization(options => options.ResourcesPath = "Resources");
var supportedCultures = new List<CultureInfo> { new CultureInfo("en"), new CultureInfo("ar") };
services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("en");
options.SupportedUICultures = supportedCultures;
});
我正在使用以下示例进行本地化,但它没有显示如何本地化错误消息: https://www.c-sharpcorner.com/article/localization-in-blazor-server/
文件夹结构图片供参考:
英文版的资源文件示例,我也有阿拉伯文文件:
在下面的屏幕截图中,您会看到正在从资源文件中正确提取字段名称,但验证消息不起作用并且仅以英文显示。
这是我的本地化数据注释错误消息的解决方案。我创建了两个资源文件,一个用于字段,另一个用于错误消息。
DisplayNameResource
用于本地化字段ErrorMessageResource
用于本地化错误消息
在视图模型中 class 使用 Display
属性来本地化字段名称。要指定资源文件,请在 Display
属性上使用 ResourceType
属性:
[Display(Name = "Address", ResourceType = typeof(DisplayNameResource))]
并且在验证属性上使用ErrorMessageResourceName
和ErrorMessageResourceType
来指定资源文件:
[Required(ErrorMessageResourceName = "RequiredError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
这是完整的例子:
public class SomeViewModel
{
[Display(Name = "Address", ResourceType = typeof(DisplayNameResource))]
[Required(ErrorMessageResourceName = "RequiredError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
[StringLength(256, ErrorMessageResourceName = "MaxLengthError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
public string Address { get; set; }
[Display(Name = "Phone", ResourceType = typeof(DisplayNameResource))]
[Required(ErrorMessageResourceName = "RequiredError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
[RegularExpression("^09([0-9]{9})$", ErrorMessageResourceName = "PhoneLengthError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
public string Phone { get; set; }
[Display(Name = "Password", ResourceType = typeof(DisplayNameResource))]
[Required(ErrorMessageResourceName = "RequiredError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
[StringLength(50, MinimumLength = 6, ErrorMessageResourceType = typeof(ErrorMessageResource), ErrorMessageResourceName = "MinxMaxLengthError")]
public string Password { get; set; }
[Display(Name = "ConfirmPassword", ResourceType = typeof(DisplayNameResource))]
[Required(ErrorMessageResourceName = "RequiredError", ErrorMessageResourceType = typeof(ErrorMessageResource))]
[StringLength(50, MinimumLength = 6, ErrorMessageResourceType = typeof(ErrorMessageResource), ErrorMessageResourceName = "MinxMaxLengthError")]
[Compare("Password", ErrorMessageResourceName = "PasswordConfirmMisMatch", ErrorMessageResourceType = typeof(ErrorMessageResource))]
public string ConfirmPassword { get; set; }
}
MaxLengthError
的错误消息是 {0} cannot be longer than {1} character
,因此 {0}
将替换为本地化的文件名,{1}
将替换为您的 256
在属性 [StringLength(256,...
之前有人问过这个问题:
我建议使用 FluentValidation 是更好的方法。这是我的 Github 存储库的 link,演示了它是如何工作的:
我没试过!
在 asp.net 核心的官方文档中有如何本地化的部分 DataAnnotations
也许你会发现一些 clues there.