ASP.NET Core Identity 1.1 چگونه پیامهای خطای خود را تامین میکند؟
نگارش 1.1 این فریم ورک به همراه یک فایل Resources.resx است که تمام پیامهای خطاهای ارائه شدهی توسط متدهای مختلف آنرا به همراه دارد. این فایل توسط کلاس IdentityErrorDescriber به نحو ذیل استفاده میشود:
public class IdentityErrorDescriber { public virtual IdentityError DefaultError() { return new IdentityError { Code = nameof(DefaultError), Description = Resources.DefaultError }; }
سپس کلاس IdentityErrorDescriber به سیستم تزریق وابستگیهای آن اضافه شده و هرجائیکه نیاز به نمایش پیامی را داشته، از آن استفاده میکند.
بنابراین همانطور که ملاحظه میکنید کلاس Resources آن ثابت است و قابل تغییر نیست. به همین جهت اگر معادل فارسی این فایل را تهیه کنیم، توسط این فریم ورک به صورت خودکار استفاده نخواهد شد.
فارسی سازی IdentityErrorDescriber
بهترین راه فارسی سازی کلاس IdentityErrorDescriber، ارث بری از آن و بازنویسی متدهای virtual آن است که اینکار در کلاس CustomIdentityErrorDescriber انجام شدهاست:
public class CustomIdentityErrorDescriber : IdentityErrorDescriber { public override IdentityError DefaultError() { return new IdentityError { Code = nameof(DefaultError), Description = "خطایی رخ دادهاست." }; }
services.AddScoped<IdentityErrorDescriber, CustomIdentityErrorDescriber>(); services.AddIdentity<User, Role>(identityOptions => { }).AddUserStore<ApplicationUserStore>() // the rest of the setting … .AddErrorDescriber<CustomIdentityErrorDescriber>() // the rest of the setting …
به این ترتیب این فریم ورک هرزمانیکه نیاز به وهلهای از نوع IdentityErrorDescriber را داشته باشد، از وهلهی فارسی سازی شدهی ما استفاده میکند.
مشکل! هنوز پس از جایگزینی سرویس IdentityServicesRegistry اصلی، تعدادی از خطاها فارسی نیستند!
اگر به کلاس PasswordValidator آن مراجعه کنید، در سازندهی کلاس یک چنین تعریفی را میتوان مشاهده کرد:
public class PasswordValidator<TUser> : IPasswordValidator<TUser> where TUser : class { public PasswordValidator(IdentityErrorDescriber errors = null) { Describer = errors ?? new IdentityErrorDescriber(); }
public class CustomPasswordValidator : PasswordValidator<User> { private readonly IUsedPasswordsService _usedPasswordsService; private readonly ISet<string> _passwordsBanList; public CustomPasswordValidator( IdentityErrorDescriber errors,// How to use CustomIdentityErrorDescriber IOptionsSnapshot<SiteSettings> configurationRoot, IUsedPasswordsService usedPasswordsService) : base(errors) public class CustomUserValidator : UserValidator<User> { private readonly ISet<string> _emailsBanList; public CustomUserValidator( IdentityErrorDescriber errors,// How to use CustomIdentityErrorDescriber IOptionsSnapshot<SiteSettings> configurationRoot ) : base(errors)
یک نکته: اگر کلاسهای زیر را سفارشی سازی کردید، تمامشان از حالت ()errors ?? new IdentityErrorDescriber در سازندهی کلاس خود استفاده میکنند. بنابراین ذکر مجدد و بازنویسی سازندهی آنها را فراموش نکنید (در حد ذکر مجدد سازندهی کلاس پایه کفایت میکند و مابقی آن توسط سیستم تزریق وابستگیها مدیریت خواهد شد):
- PasswordValidator
- RoleManager
- RoleStore
- UserStore
- UserValidator
- RoleValidator
کدهای کامل این سری را در مخزن کد DNT Identity میتوانید ملاحظه کنید.