asp.net-mvc – Unity使用参数将依赖项注入MVC​​过滤器类

我正在使用 Unity.MVC4依赖注入来访问我的服务.注入到我的Controller构造函数中时,一切都正常,但我现在要做的是在我的过滤器类中使用属​​性注入,这样我就可以从内部访问我的数据库了.

在我开始这个问题之前,我用Google搜索并尝试了不同的示例,但我找不到适合我的解决方案..

Bootstrapper.cs

public static class Bootstrapper
{
    public static IUnityContainer Initialise()
    {
        var container = BuildUnityContainer();

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

        return container;
    }

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();
        container.RegisterType<IAccountRepository,AccountRepository>();
        container.RegisterType<IAdministrationRepository,AdministrationRepository>();
        container.RegisterType<IUploadDirectlyRepository,UploadDirectlyRepository>();
        container.RegisterType<IUserRepository,UserRepository>();
        container.RegisterType<INewsRepository,NewsRepository>();
        container.RegisterType<IContactRepository,ContactRepository>();

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        // e.g. container.RegisterType<ITestService,TestService>();    
        RegisterTypes(container);

        return container;
    }

    public static void RegisterTypes(IUnityContainer container)
    {

    }
}

的Application_Start

public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterallAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            Bootstrapper.Initialise();
        }
    }

工作实例

public class UserController : Controller
{
    private readonly IUserRepository _userRepository;

    public UserController(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public ActionResult GetUser(int userID)
    {
        var user = _userRepository.GetUser(userID)

        return View(user);
    }
}

我要向您展示的以下代码是我想要在我的操作中使用的filter属性.
我想传入一个字符串数组类型的参数,以便我可以验证是否允许当前用户访问该操作.

在我的应用程序中,有两种类型的用户,帐户所有者和访客.对于帐户所有者而言,所有操作都是完全开放的,但对于访客而言,操作因操作而异.例如,某个操作可能要求您拥有至少三个权限之一(读取,写入和编辑).

过滤:

public class ClaimsAuthorizeAccountAccess : AuthorizeAttribute
{
    private IAccountRepository _accountRepository { get; set; }
    private String[] _permissions { get; set; }

    public ClaimsAuthorizeAccountAccess(IAccountRepository accountRepository,params String[] permissions)
    {
        _permissions = permissions;
        _accountRepository = accountRepository;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (HttpContext.Current.User.IsInRole("Account Owner"))
        {
            base.OnAuthorization(filterContext);
        }
        else
        {
            ClaimsIdentity claimsIdentity = (ClaimsIdentity)HttpContext.Current.User.Identity;
            List<AccountLinkPermissionDTO> accountLinkPermissions = new List<AccountLinkPermissionDTO>();

            int accountOwnerID = 0;
            Int32.TryParse(claimsIdentity.Claims.Where(c => c.Type == "AccountOwnerID").Select(c => c.Value).SingleOrDefault(),out accountOwnerID);
            int guestID = 0;
            Int32.TryParse(claimsIdentity.Claims.Where(c => c.Type == ClaimTypes.Sid).Select(c => c.Value).SingleOrDefault(),out guestID);

            //NULL
            accountLinkPermissions = _accountRepository.GetAccountLinkPermissions(accountOwnerID,guestID);

            if (accountLinkPermissions != null)
            {
                List<string> accountLinkPermissionsToString = accountLinkPermissions.Select(m => m.Permission.Name).ToList();
                int hits = accountLinkPermissionsToString.Where(m => _permissions.Contains(m)).Count();

                if (hits > 0)
                {
                    base.OnAuthorization(filterContext);
                }
            }
            else
            {
                //Guest doesnt have right permissions

                filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary {
                        { "action","AccessDenied" },{ "controller","Account" }});
            }
        }
    }
}

如果我使用这个过滤器,它看起来像..

[ClaimsAuthorizeAccountAccess("File read","File write,File edit")]
public ActionResult Files()
{
    return View();
}

但是这不起作用,因为过滤器需要两个参数(IRepository和string []).显然,这里也不可能使用构造函数注入.

然后我尝试实现可以​​在here找到的John Allers解决方案.它看起来很有希望,但它给了我这个错误

An exception of type
‘Microsoft.Practices.Unity.ResolutionFailedException’ occurred in
Microsoft.Practices.Unity.dll but was not handled in user code

Additional information: Resolution of the dependency Failed,type =
“Fildela.ClaimsAuthorizeAccountAccess”,name = “(none)”.

Exception occurred while: while resolving.

Exception is: InvalidOperationException – The property
_accountRepository on type Fildela.ClaimsAuthorizeAccountAccess is not settable.

At the time of the exception,the container was:

Resolving Fildela.ClaimsAuthorizeAccountAccess,(none)

关于如何解决这个坏男孩的任何建议?

谢谢!

解决方法

首先安装官方软件包,Unity.Mvc而不是Unity.MVC4.该软件包自动安装并注册UnityFilterattributeFilterProvider,我们需要它来进行属性的依赖注入.您可以通过查看App_Start>来检查Unity是否配置良好. UnityMvcActivator的Start方法.您必须看到以下两行:
public static void Start()
{
    // other codes

    FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterattributeFilterProvider>().First());
    FilterProviders.Providers.Add(new UnityFilterattributeFilterProvider(container));
}

现在,您可以将[Dependency]属性添加到过滤器的公共属性中.

public class ClaimsAuthorizeAccountAccess : AuthorizeAttribute
{
    [Dependency]
    public IAccountRepository AccountRepository { get; set; }
    private String[] _permissions { get; set; }

    public ClaimsAuthorizeAccountAccess(params String[] permissions)
    {
        _permissions = permissions;
    }
}

相关文章

### 创建一个gRPC服务项目(grpc服务端)和一个 webapi项目(...
一、SiganlR 使用的协议类型 1.websocket即时通讯协议 2.Ser...
.Net 6 WebApi 项目 在Linux系统上 打包成Docker镜像,发布为...
一、 PD简介PowerDesigner 是一个集所有现代建模技术于一身的...
一、存储过程 存储过程就像数据库中运行的方法(函数) 优点:...
一、Ueditor的下载 1、百度编辑器下载地址:http://ueditor....