过滤器的WebAPI团结 [英] WebApi Filter Unity

查看:250
本文介绍了过滤器的WebAPI团结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Environement:团结和ASP.NET MVC的WebAPI
我按照从网页样本 HTTP: //www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-dependency-injection
之后做了一些修改,我找到一种方式来注入用于过滤的Controler

Environement : Unity and ASP.NET MVC WEBAPI I follow the sample from the webpage http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-dependency-injection And after to do some modifications, I find a way to inject Filter for Controler.

我用这个code在boostrapper.cs

I used this code in the boostrapper.cs

var container = new UnityContainer();
container.RegisterInstance<IFilterProvider>("FilterProvider", new    FilterProvider(container));
container.RegisterInstance<IActionFilter>("LogActionFilter", new TraceActionFilter());

我添加了这个类FilterProvider

I add this class FilterProvider

public class FilterProvider : IFilterProvider
{
    private IUnityContainer container;

    public FilterProvider(IUnityContainer container)
    {
        this.container = container;
    }

    public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        foreach (IActionFilter actionFilter in this.container.ResolveAll<IActionFilter>())
        {
            yield return new Filter(actionFilter, FilterScope.First, null);
        }
    }
}

每一个方法被称为该控制器实现的一类叫做时间所以,我可以看到code堪称一流TraceActionFilter。

So each time a method is called by called a class which implemented Controller, I can see the code called in the class TraceActionFilter.

public class TraceActionFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.HttpContext.Trace.Write("OnActionExecuted");
        filterContext.HttpContext.Trace.Write("Action " + filterContext.ActionDescriptor.ActionName);
        filterContext.HttpContext.Trace.Write("Controller " + filterContext.ActionDescriptor.ControllerDescriptor.ControllerName);
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
                filterContext.HttpContext.Trace.Write("OnActionExecuting");
                filterContext.HttpContext.Trace.Write("Action " + filterContext.ActionDescriptor.ActionName);
                filterContext.HttpContext.Trace.Write("Controller " + filterContext.ActionDescriptor.ControllerDescriptor.ControllerName);
    }
} 

但我不网页,任何样品或正确的方式允许做同样的事情上找到:注入过滤器添加有关的WebAPI相同的行为。
唯一的办法是发现通过使用标签手动添加一个过滤器,不使用依赖注入。
你能提供什么帮助?

But I don't find on the web, any sample or right way permitting to do the same thing : inject filter for add the same behavior about the WebApi. The only way find is to add manually a filter by using tag, not used the dependency injection. Can you provide any help?

最好的问候,
亚历山大

Best regards, Alexandre

[更新第一个答案后]
我启动命令安装封装Unity.AspNet.WebApi允许访问到UnityConfig。
我加在Global.asax

[UPDATE AFTER THE FIRST ANSWER] I launch the command Install-Package Unity.AspNet.WebApi to permit to access to UnityConfig. I add in the global.asax

    protected void Application_Start()
    {
        Bootstrapper.Initialise();
        UnityWebApiActivator.Start();
        ConfigureApi(GlobalConfiguration.Configuration); //line added

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

我添加的方法ConfigureApi()

I add in the method ConfigureApi()

    void ConfigureApi(HttpConfiguration config)
    {
        var unity = new UnityContainer();
        unity.RegisterType<ProductsApiController>();
        unity.RegisterType<CategoriesApiController>();

        unity.RegisterType<IProductService, ProductService>(
            new HierarchicalLifetimeManager());
        unity.RegisterType<IProductsDatabase, ProductsDatabase>(
             new HierarchicalLifetimeManager());

        unity.RegisterType<ICategorieService, CategorieService>(
            new HierarchicalLifetimeManager());
        unity.RegisterType<ICategoriesDatabase, CategoriesDatabase>(
             new HierarchicalLifetimeManager());

        unity.RegisterType<ILogProvider, ElmahProvider>(
             new HierarchicalLifetimeManager());

        unity.RegisterType<IRootController, RootController>(
            new HierarchicalLifetimeManager());

        config.DependencyResolver = new IoCContainer(unity);

        //ADDED PARTS
        var providers = GlobalConfiguration.Configuration.Services.GetFilterProviders().ToList();
        config.Services.Add(
            typeof(System.Web.Http.Filters.IFilterProvider),
            new Filter2Provider(UnityConfig.GetConfiguredContainer()));

        var defaultprovider = providers.First(p => p is System.Web.Http.Filters.ActionDescriptorFilterProvider);
        config.Services.Remove(typeof(System.Web.Http.Filters.IFilterProvider), defaultprovider);            
    }

当我调用该方法... API / categoriesapi / GETALL
在TraceActionFilter断点不叫。

When I call the method ...api/categoriesapi/GetAll The breakPoint in TraceActionFilter is not called.

什么想法?我continu搜索。

any idea? I continu to search.

推荐答案

您需要创建一个自定义System.Web.Http.Filters.FilterProvider(注意,MVC具有相同名称的类在不同的命名空间):

You will need to create a custom System.Web.Http.Filters.FilterProvider (be aware that MVC has classes with the same names in a different namespace):

public class UnityActionFilterProvider 
    : System.Web.Http.Filters.ActionDescriptorFilterProvider, 
      System.Web.Http.Filters.IFilterProvider
{
    private readonly IUnityContainer container;

    public UnityActionFilterProvider(IUnityContainer container)
    {
        this.container = container;
    }

    public new IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, 
        HttpActionDescriptor actionDescriptor)
    {
        foreach (IActionFilter actionFilter in container.ResolveAll<IActionFilter>())
        {
            // TODO: Determine correct FilterScope
            yield return new FilterInfo(actionFilter, FilterScope.Global);
        }
    }
}

然后你需要在启动时设置过滤器供应商:

Then you will need to set the filter provider at startup:

var providers = 
    GlobalConfiguration.Configuration.Services.GetFilterProviders().ToList();

GlobalConfiguration.Configuration.Services.Add(
    typeof(System.Web.Http.Filters.IFilterProvider),
    new UnityActionFilterProvider(UnityConfig.GetConfiguredContainer()));

var defaultprovider = providers.First(p => p is ActionDescriptorFilterProvider);

GlobalConfiguration.Configuration.Services.Remove(
    typeof(System.Web.Http.Filters.IFilterProvider), 
    defaultprovider);

您应该使用上面的团结引导程序进行的ASP.NET Web API

使用属性类似的问题:的ASP.NET Web API - 把依赖注入ActionFilterAttribute

A similar question using attributes: ASP.NET Web API - Inject Dependencies Into ActionFilterAttribute

由于您使用的容器,以保持过滤器列表,那么你可以只注册FilterInfo的,而不是直接IActionFilter。

Since you are using the container to maintain the list of Filters then you could just register the FilterInfo directly instead of IActionFilter.

这篇关于过滤器的WebAPI团结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆