Asp.net web api 在运行时禁用ApicController

Asp.net web api 在运行时禁用ApicController,asp.net-web-api,Asp.net Web Api,我有一个ASP.NET Web API(.NET 4)应用程序,它有几个控制器。我们将在IIS上运行多个Web API应用程序实例,但有一个区别。在某些IIS实例下,只有某些控制器可用。我的想法是在实例启动时禁用/卸载不适用于实例的控制器 任何人都可以得到一些信息来指导我在这方面的正确方向?与其卸载控制器,我想我应该创建一个自定义的Authorize属性,在决定授予授权时查看实例信息 您可以将以下内容添加到类级别的每个控制器中,也可以将其添加到单个控制器操作中: [ControllerAutho

我有一个ASP.NET Web API(.NET 4)应用程序,它有几个控制器。我们将在IIS上运行多个Web API应用程序实例,但有一个区别。在某些IIS实例下,只有某些控制器可用。我的想法是在实例启动时禁用/卸载不适用于实例的控制器


任何人都可以得到一些信息来指导我在这方面的正确方向?

与其卸载控制器,我想我应该创建一个自定义的Authorize属性,在决定授予授权时查看实例信息

您可以将以下内容添加到类级别的每个控制器中,也可以将其添加到单个控制器操作中:

[ControllerAuthorize(AuthorizedUserSources=new[]{“IISInstance 1”、“IISInstance 2”和“…”}]
以下是该属性的代码:

public class ControllerAuthorize:AuthorizeAttribute
{
公共控制器权限()
{
UnauthorizedAccessMessage=“您没有查看此内容所需的访问权限。”;
}
//属性允许使用数组而不是单个字符串。
私有字符串[]_授权的资源;
公共字符串UnauthorizedAccessMessage{get;set;}
公共字符串[]授权的资源
{
获取{return}authorizedSources??新字符串[0];}
设置{u authorizedSources=value;}
}
//如果IIS实例ID与任何AllowedSources匹配,则返回true。
受保护的覆盖bool AuthorizeCore(HttpContextBase httpContext)
{
if(httpContext==null)
抛出新ArgumentNullException(“httpContext”);
//如果未提供任何源,则返回true,假设“无”表示任何源。
如果(!AuthorizedSources.Any())
返回true;
返回AuthorizedSources.Any(ut=>ut==httpContext.ApplicationInstance.Request.ServerVariables[“实例ID]”);
}

您可以通过装饰DefaultHttpControllerActivator将自己的自定义
IHttpControllerActivator
放入。只需在内部检查设置,并仅在允许的情况下创建控制器

当您从Create方法返回null时,用户将收到404notfound消息

我的示例显示了正在检查的应用程序设置(App.Config或Web.Config)中的一个值,但很明显,这可能会影响任何其他环境感知条件

public类YourCustomControllerActivator:IHttpControllerActivator
{
专用只读IHttpControllerActivator_default=new DefaultHttpControllerActivator();
public YourCustomControllerActivator()
{
}
公共IHTTP控制器创建(HttpRequestMessage请求、HttpControllerDescriptor控制器Descriptor、,
类型控制器类型)
{
if(ConfigurationManager.AppSettings[“MySetting”]=“Off”)
{
//或者聪明地在controllerDescriptor.GetCustomAttributes()中查找控制器上的属性;
//或者使用控制器名controllerDescriptor.ControllerName
//此示例使用
if(controllerType==typeof(MyController)||
controllerType==typeof(EtcController))
{
返回null;
}
}
返回_default.Create(请求、controllerDescriptor、controllerType);
}
}   
您可以按如下方式切换激活器:

GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator),new YourCustomControllerActivator());
更新


我已经有一段时间没有研究这个问题了,但是如果我今天要解决这个问题,我会稍微改变一下方法,并使用一个自定义方法。这个方法在activator之前调用,使得启用和禁用控制器的效率略高一些…(尽管另一种方法确实有效)。如果要打开/关闭控制器并具有默认的“捕获所有”路由控制器,则应能够修饰或继承
DefaultHttpControllerSelector

IHttpControllerActivator
实现不会禁用使用属性路由定义的路由。使用
IHttpControllerAc关闭tivator
禁用控制器,但当请求路由时,它不会命中“一网打尽”路由控制器-它只是尝试命中已删除的控制器,并且不会返回任何已注册的控制器。

路由会影响哪些控制器“可用”。在应用程序启动时,您可以使用RouteTable.Routes.MapHttpRoute仅映射roUTE到您希望由服务公开的收集器。您可能希望删除默认路由并显式定义每个控制器的路由。我的解决方案(stackoverflow链接):+1-聪明,如果你能让它读取配置设置来确定控制器是否也被授权,那就太好了。因为同一个应用程序有多个实例,我强烈建议在web.config文件中配置它。尝试检测实例或应用池没有任何意义,因为管理员我已经控制了它,他们可能会因为任何原因改变它。感谢大家在这方面的帮助。我花了一段时间重新开始这个项目。感谢@MarkJones你的代码发挥了魅力,我将它与我自己的DefaultAssembliesResolver结合使用,以获得所需的结果。