【问题标题】:Localizer dependency Injection without constructor没有构造函数的本地化依赖注入
【发布时间】:2019-04-04 07:12:49
【问题描述】:

我正在 .net 核心中创建自定义授权。一切正常,但我想在属性响应中添加本地化程序。

下面是我的代码

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
    public class CustomAuthorizeFilters : AuthorizeAttribute, IAuthorizationFilter
    {
        public CustomAuthorizeFilters()
        { }

        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var User = context.HttpContext.User;

            if (!User.Identity.IsAuthenticated)
                return;

            using (var account_help = new AccountHelpers(Startup.ConnectionString))
            {
                var userId = Guid.Parse(new security.AesAlgoridhm().Decrypt(User.Claims.Where(x => x.Type == JwtRegisteredClaimNames.Sid)?.FirstOrDefault().Value));
                ProfileResponse user = new ProfileResponse();

                if (user == null)
                    context.Result = new CustomResultFilters("error_access_token_expired", 401);

                if (!user.EmailConfirmed)
                    context.Result = new CustomResultFilters("bad_response_account_not_confirmed", 400);

                if (!user.Active)
                    context.Result = new CustomResultFilters("bad_response_account_inactive", 400);
            }
        }
    }

我试过像这样在构造函数中传递本地化程序,但是当我从控制器传递一个参数时,它给了我错误

属性构造函数参数的类型不是有效的属性参数类型

  IStringLocalizer<dynamic> localize { get; set; }
  public CustomAuthorizeFilters(IStringLocalizer<dynamic> localizer = null)
  {
            localize = localizer;
  }

我知道属性只支持原始数据类型,这就是为什么我也尝试将直接依赖注入为

context.HttpContext.RequestServices.GetService(typeof(IStringLocalizer<dynamic>));

但这会导致错误:

无法从对象转换为定位器。

【问题讨论】:

  • 您不能使用动态作为类型参数。字符串本地化程序需要 TYPE。该类型用于定位包含翻译的资源文件,即IStringLocalizer&lt;MyController&gt; 将查找名为MyController.xx-yy.resx 的资源文件。如果您想要共享本地化资源,请使用固定类或虚拟类,例如IStringLocalizer&lt;SharedResources&gt; 其中SharedResources 只是一个空类public class SharedResources { }
  • 另请参阅docs,了解如何使用ServiceFilter 属性将依赖项注入到属性中
  • 你可以尝试在共享资源中定义本地化字符串,并传递SharedResource,参考Make the app's content localizable

标签: c# .net asp.net-core


【解决方案1】:

您可以使用shared 资源并获得这样的本地化器

Type localizerType = typeof(IStringLocalizer<SharedResource>);
IStringLocalizer localizer = (IStringLocalizer)context.HttpContext.RequestServices.GetService(localizerType );

或者,如果您使用每个控制器的资源,您可以从 context 获取控制器类型并获取控制器本地化器

public void OnAuthorization(AuthorizationFilterContext context)
{
    //..
    Type localizerType = GetLocalizerType(context);
    IStringLocalizer localizer = (IStringLocalizer)context.HttpContext.RequestServices.GetService(localizerType);
    //..
}

private Type GetLocalizerType(AuthorizationFilterContext context)
{
    var controllerType = (context.ActionDescriptor as ControllerActionDescriptor).ControllerTypeInfo;
    return typeof(IStringLocalizer<>).MakeGenericType(controllerType);
}

【讨论】:

  • 谢谢,这真的很有帮助。
猜你喜欢
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-17
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
相关资源
最近更新 更多