DataAnnotations aspnet核心中的本地化

时间:2017-02-06 09:11:18

标签: asp.net-core

我在一个解决方案中有2个项目。其中一个名为UICORE,另一个名为DomainCore。 UICore是一个ASPNETCORE项目,它有我的控制器和视图。 DomainCore是一个包含所有实体类的类库。我想使用本地化的DataAnnotations。我研究过“https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization”,但我无法让它为我工作。

3 个答案:

答案 0 :(得分:1)

如果Domain和View模型的DataAnnotations遇到您的问题(或其中的一部分),我建议使用此方法。

如果没有,请不要downvote。它可能对DataAnnotations标记很有用。

为了编写一次DataAnnotations,请使用抽象类。在New实体的这个例子中,我将抽象类命名为NewMetaData。

DomainCore项目:

namespace myProject.DomainCore
{
    public class New : NewMetaData
    {
        public Guid Id { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public DateTime Date { get; set; }
    }

    public abstract class NewMetaData
    {
        [Required(ErrorMessage = "New Title is required")]
        [StringLength(maximumLength:150, ErrorMessage = "New Title length must not exceed 150 characters")]
        [Display(Name = "Title on New")]
        private string Title { get; set; }  //pay attention to privates

        [Required(ErrorMessage = "New Content is required")]
        [Display(Name = "Content of New")]
        private string Content { get; set; }

        [Required]
        [Display(Name = "Publish Date")]
        private DateTime Date { get; set; }        

    }
}

UICore项目中的viewmodel类也必须继承NewMetaData类:

namespace myProject.UICore.Models.News
{
    public class NewCreateModel: NewMetaData
    {
        public string Title { get; set; }
        [AllowHtml]
        public string Content { get; set; }
    }

    public class NewDetailsModel :NewMetaData
    {
        [HiddenInput(DisplayValue = false)]
        public Guid Id { get; set; }
        public string Url { get; set; }
        public string Title { get; set; }
        public string Content { get; set; } 
    }
}

正如您所看到的,您可以向UICore中的AllowHtml,HiddenInput和...等属性添加额外的DataAnotations,并且仍然保持基本Annotations不受影响。

这是一次最简单的跨项目方法,用于对模型进行一次注释并多次使用它们。

希望它有所帮助。

答案 1 :(得分:0)

也许这会有所帮助: https://damienbod.com/2015/10/24/using-dataannotations-and-localization-in-asp-net-5-mvc-6/

您需要将数据声明本地化添加到共享资源,并将其添加到每个控制器,查看它与本地化响应一起使用的位置。

答案 2 :(得分:0)

您必须在启动文件中配置本地化,并添加DataAnnotations本地化选项;

services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddViewLocalization(o=>o.ResourcesPath = "ResourcesFolder")
.AddDataAnnotationsLocalization(o=> {
    var type = typeof(MyResource);
    var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
    var factory = services.BuildServiceProvider().GetService<IStringLocalizerFactory>();
    var localizer = factory.Create("MyResource", assemblyName.Name);
    o.DataAnnotationLocalizerProvider = (t, f) => localizer;
})

这将本地化数据属性,例如:

[Required(ErrorMessage= "...")]
[StringLength(ErrorMessage= "...")]
[Range(ErrorMessage= "...")]

以此类推。

,但是您仍然必须配置ModelBinding错误消息(例如:检查数字,空值等)

services.AddMvc()
.AddMvcOptions(o =>
        {
            var type = typeof(MyResource);
            var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
            var factory = services.BuildServiceProvider().GetService<IStringLocalizerFactory>();
            var localizer = factory.Create("MyResource", assemblyName.Name);

            o.ModelBindingMessageProvider
                .SetAttemptedValueIsInvalidAccessor((x, y) => localizer["'{0}' is not a valid value for '{1}'", x, y]);

            o.ModelBindingMessageProvider
                .SetValueMustBeANumberAccessor((x) => localizer["'{0}' must be a number.", x]);
        });

如果您已经实施了身份系统,则必须通过重写IdentityErrorDescriber方法来本地化身份错误消息(重复的电子邮件,密码策略等);

public class LocalizedIdentityErrorDescriber : IdentityErrorDescriber
{
    public override IdentityError DuplicateEmail(string email)
    {
        return new IdentityError
        {
            Code = nameof(DuplicateEmail),
            Description = string.Format(LocalizedIdentityErrorMessages.DuplicateEmail, email)
        };
    }

    public override IdentityError DuplicateUserName(string userName)
    {
        return new IdentityError
        {
            Code = nameof(DuplicateUserName),
            Description = string.Format(LocalizedIdentityErrorMessages.DuplicateUserName, userName)
        };
    }

    public override IdentityError InvalidEmail(string email)
    {
        return new IdentityError
        {
            Code = nameof(InvalidEmail),
            Description = string.Format(LocalizedIdentityErrorMessages.InvalidEmail, email)
        };
    }

    public override IdentityError DuplicateRoleName(string role)
    {
        return new IdentityError
        {
            Code = nameof(DuplicateRoleName),
            Description = string.Format(LocalizedIdentityErrorMessages.DuplicateRoleName, role)
        };
    }

    public override IdentityError InvalidRoleName(string role)
    {
        return new IdentityError
        {
            Code = nameof(InvalidRoleName),
            Description = string.Format(LocalizedIdentityErrorMessages.InvalidRoleName, role)
        };
    }

    public override IdentityError InvalidToken()
    {
        return new IdentityError
        {
            Code = nameof(InvalidToken),
            Description = LocalizedIdentityErrorMessages.InvalidToken
        };
    }

    public override IdentityError InvalidUserName(string userName)
    {
        return new IdentityError
        {
            Code = nameof(InvalidUserName),
            Description = string.Format(LocalizedIdentityErrorMessages.InvalidUserName, userName)
        };
    }

    public override IdentityError LoginAlreadyAssociated()
    {
        return new IdentityError
        {
            Code = nameof(LoginAlreadyAssociated),
            Description = LocalizedIdentityErrorMessages.LoginAlreadyAssociated
        };
    }

    public override IdentityError PasswordMismatch()
    {
        return new IdentityError
        {
            Code = nameof(PasswordMismatch),
            Description = LocalizedIdentityErrorMessages.PasswordMismatch
        };
    }

    public override IdentityError PasswordRequiresDigit()
    {
        return new IdentityError
        {
            Code = nameof(PasswordRequiresDigit),
            Description = LocalizedIdentityErrorMessages.PasswordRequiresDigit
        };
    }

    public override IdentityError PasswordRequiresLower()
    {
        return new IdentityError
        {
            Code = nameof(PasswordRequiresLower),
            Description = LocalizedIdentityErrorMessages.PasswordRequiresLower
        };
    }

    public override IdentityError PasswordRequiresNonAlphanumeric()
    {
        return new IdentityError
        {
            Code = nameof(PasswordRequiresNonAlphanumeric),
            Description = LocalizedIdentityErrorMessages.PasswordRequiresNonAlphanumeric
        };
    }

    public override IdentityError PasswordRequiresUniqueChars(int uniqueChars)
    {
        return new IdentityError
        {
            Code = nameof(PasswordRequiresUniqueChars),
            Description = string.Format(LocalizedIdentityErrorMessages.PasswordRequiresUniqueChars, uniqueChars)
        };
    }

    public override IdentityError PasswordRequiresUpper()
    {
        return new IdentityError
        {
            Code = nameof(PasswordRequiresUpper),
            Description = LocalizedIdentityErrorMessages.PasswordRequiresUpper
        };
    }

    public override IdentityError PasswordTooShort(int length)
    {
        return new IdentityError
        {
            Code = nameof(PasswordTooShort),
            Description = string.Format(LocalizedIdentityErrorMessages.PasswordTooShort, length)
        };
    }

    public override IdentityError UserAlreadyHasPassword()
    {
        return new IdentityError
        {
            Code = nameof(UserAlreadyHasPassword),
            Description = LocalizedIdentityErrorMessages.UserAlreadyHasPassword
        };
    }

    public override IdentityError UserAlreadyInRole(string role)
    {
        return new IdentityError
        {
            Code = nameof(UserAlreadyInRole),
            Description = string.Format(LocalizedIdentityErrorMessages.UserAlreadyInRole, role)
        };
    }

    public override IdentityError UserNotInRole(string role)
    {
        return new IdentityError
        {
            Code = nameof(UserNotInRole),
            Description = string.Format(LocalizedIdentityErrorMessages.UserNotInRole, role)
        };
    }

    public override IdentityError UserLockoutNotEnabled()
    {
        return new IdentityError
        {
            Code = nameof(UserLockoutNotEnabled),
            Description = LocalizedIdentityErrorMessages.UserLockoutNotEnabled
        };
    }

    public override IdentityError RecoveryCodeRedemptionFailed()
    {
        return new IdentityError
        {
            Code = nameof(RecoveryCodeRedemptionFailed),
            Description = LocalizedIdentityErrorMessages.RecoveryCodeRedemptionFailed
        };
    }

    public override IdentityError ConcurrencyFailure()
    {
        return new IdentityError
        {
            Code = nameof(ConcurrencyFailure),
            Description = LocalizedIdentityErrorMessages.ConcurrencyFailure
        };
    }

    public override IdentityError DefaultError()
    {
        return new IdentityError
        {
            Code = nameof(DefaultError),
            Description = LocalizedIdentityErrorMessages.DefaultIdentityError
        };
    }
}

在此示例中,所有具有本地访问权限的本地化错误消息均在带有公共访问修饰符的名为LocalizedIdentityErrorMessages的资源文件中提供。

您可以查看有关本地化的这些文章,其中包含GitHub上的实时演示和示例项目。

开发多元文化的网络应用程序: http://www.ziyad.info/en/articles/10-Developing_Multicultural_Web_Application

本地化数据注释: http://www.ziyad.info/en/articles/16-Localizing_DataAnnotations

本地化身份错误消息: http://www.ziyad.info/en/articles/20-Localizing_Identity_Error_Messages

本地化ModelBinding错误消息: http://www.ziyad.info/en/articles/18-Localizing_ModelBinding_Error_Messages

客户端验证: http://www.ziyad.info/en/articles/19-Client_Side_Validation