在一个Web应用程序的API什么时候我可以拦截URI参数和路线相应的电话? [英] At what point in a Web API app can I intercept the URI arguments and route the calls accordingly?

查看:207
本文介绍了在一个Web应用程序的API什么时候我可以拦截URI参数和路线相应的电话?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请注意:这个问题确实是有点类似的这个,但我想我可以把它放在一个更简单和更具体的方式。

Note: This question is indeed somewhat similar to this one, but I think I can put it in a simpler and more specific way.

我使用温莎城堡到拦截URI传递给我的Web API应用程序来注册相应的具体类到控制器的构造函数。

I'm using Castle Windsor to intercept the URI passed to my Web API app to register the appropriate concrete class to the Controller's constructor.

我希望能够做的是通过一个站点号对URI,或许总是作为第一或最后一个精氨酸。 IOW,站点42,而不是

What I want to be able to do is pass a "site number" on the URI, perhaps always as either the first or last arg. IOW, for site 42, instead of

http://localhost:28642/api/platypi/GetAll

...这将是:

http://localhost:28642/api/platypi/42/GetAll

- 或:

http://localhost:28642/api/platypi/GetAll/42

在我的Web API的应用程序第一次看到/拦截URI,我想指出,网站数,这样我可以将所需的具体信息库由城堡温莎注册。我希望能够做到这一点:

When my Web API app first "sees"/intercepts the URI, I want to note that site number so that I can assign the desired concrete Repository to be registered by Castle Windsor. I want to be able to do this:

public class RepositoriesInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        if (siteNum == 42)
        {
            container.Register(
            Component.For<IDepartmentRepository>().ImplementedBy<DepartmentRepository42>().LifestylePerWebRequest(),
                Component.For<IInventoryItemRepository>().ImplementedBy<InventoryItemRepository42>().LifestylePerWebRequest(),
            . . .
        }
        else if (siteNum = 77)
        {
            container.Register(
        Component.For<IDepartmentRepository>().ImplementedBy<DepartmentRepository77>().LifestylePerWebRequest(),
                Component.For<IInventoryItemRepository>().ImplementedBy<InventoryItemRepository77>().LifestylePerWebRequest(),
            . . .
        }

$ b。
$ b

在这种方式,我可以给网站42的数据,现场77的数据(每个站点使用了共享一个通用的架构不同的数据库)。

In this way I can give site 42 its data, site 77 its data (each site uses a different database that share a common schema).

所以:?在这点上我的Web API的应用程序的生命周期,我可以劫持URI,这样才能分配适当的VAL到全球siteNum变量,因此,它已被赋予了IWindsorInstaller方法运行之前

So: At which point in my Web API app's lifecycle can I hijack the URI, so as to assign the appropriate val to the global siteNum variable, so that it has been assigned before the IWindsorInstaller method runs?

由于板岩先生,但如果我是这样做,这将控制器代码:

Thanks to Mr. Slate, but if I were to do that, would this Controller code:

public DepartmentsController(IDepartmentRepository deptsRepository)
{
    if (deptsRepository == null)
    {
        throw new ArgumentNullException("deptsRepository");
    }
    _deptsRepository = deptsRepository;
}



...成为:

...become:

public DepartmentsController(IDepartmentRepository deptsRepository)
{
    if (deptsRepository == null)
    {
        throw new ArgumentNullException("deptsRepository");
    }
    _deptsRepository = deptsRepository(siteNum);
}



...或者???

...or???

和我仍然留下了的我在哪里拦截传入的URI温莎城堡前/控制器得到它,这样我可以设置适当的值全局/ siteNum VAR问题?

And I'm still left with the problem of where do I intercept the incoming URI before Castle Windsor / the Controller gets it, so that I can set the appropriate value to the global / siteNum var?

推荐答案

有一些扩展点,你可以用它来实现这一点,我个人使用一个类似的结果。

There are a number of extensions points that you can use to achieve this, personally I use this one for a similar result.

延长 IModelBinder 像这样创建自定义模型绑定:

Create a custom model binder by extending IModelBinder something like this:

public class SiteManagerModelBinder : IModelBinder
    {
        #region IModelBinder Members

        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.Model != null)
            {
                throw new InvalidOperationException("Cannot update instances");
            }

            // Apply your condition to determine if site number is in Url.
            if (controllerContext.RouteData.Values['siteNum']!=null)
            {
               // probably want to resolve this from container just hard coding as example, assumption is that SiteManager, does the repository bits for you.
               return new SiteManager((int)controllerContext.RouteData.Values['siteNum']);
            }

            return null;
        }

        #endregion
    }



好吧所以现在我们绝对tneed注册一个新的模型绑定器:

Okay so now we jus tneed to register our new ModelBinder:

    protected void Application_Start()
    { 
        ModelBinders.Binders.Add(typeof(SiteManager), new SiteManagerModelBinder ());



好吧,现在在我们的控制器所有我们要做的就是添加SiteManager任何行动的一个参数,它。将我们的模型绑定器得到填充

Okay and now in our controller all we do is add the SiteManager as a parameter of any Action and it will get filled in by our ModelBinder.

public class DepartmentsController: Controller {

    public ActionResult AnyAction(SiteManager siteManager, int whateverElse, ViewModel model)
    {

    }

}

这篇关于在一个Web应用程序的API什么时候我可以拦截URI参数和路线相应的电话?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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