我有一个 ASP.NET Web API (.NET 4) 应用程序,它有几个控制器。我们将在 IIS 上运行几个 Web API 应用程序实例,但有一点不同。在某些 IIS 实例下,只有某些控制器可用。我在想的是在实例启动时禁用/卸载不适用于实例的控制器。
任何人都可以获得一些可以指导我正确方向的信息吗?
我有一个 ASP.NET Web API (.NET 4) 应用程序,它有几个控制器。我们将在 IIS 上运行几个 Web API 应用程序实例,但有一点不同。在某些 IIS 实例下,只有某些控制器可用。我在想的是在实例启动时禁用/卸载不适用于实例的控制器。
任何人都可以获得一些可以指导我正确方向的信息吗?
您可以通过装饰 DefaultHttpControllerActivator 来放入您自己的自定义IHttpControllerActivator
。在里面只检查一个设置,如果允许,只创建控制器。
当您从 Create 方法返回 null 时,用户将收到 404 Not Found 消息。
我的示例显示了正在检查应用程序设置(App.Config 或 Web.Config)中的值,但显然这可能是任何其他环境感知条件。
public class YourCustomControllerActivator : IHttpControllerActivator
{
private readonly IHttpControllerActivator _default = new DefaultHttpControllerActivator();
public YourCustomControllerActivator()
{
}
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor,
Type controllerType)
{
if (ConfigurationManager.AppSettings["MySetting"] == "Off")
{
//Or get clever and look for attributes on the controller in controllerDescriptor.GetCustomAttributes<>();
//Or use the contoller name controllerDescriptor.ControllerName
//This example uses the type
if (controllerType == typeof (MyController) ||
controllerType == typeof (EtcController))
{
return null;
}
}
return _default.Create(request, controllerDescriptor, controllerType);
}
}
您可以像这样切换激活器:
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new YourCustomControllerActivator());
更新
自从我查看这个问题以来已经有一段时间了,但是如果我今天要解决它,我会稍微改变方法并使用 custom IHttpControllerSelector
。这在激活器之前调用,并为启用和禁用控制器提供了一个更有效的位置......(尽管其他方法确实有效)。您应该能够装饰或继承自DefaultHttpControllerSelector
.
我认为我不会卸载控制器,而是创建一个自定义 Authorize 属性,该属性在决定授予授权时查看实例信息。
您可以将以下内容添加到类级别的每个控制器中,或者您也可以将其添加到各个控制器操作中:
[ControllerAuthorize (AuthorizedUserSources = new[] { "IISInstance1","IISInstance2","..." })]
这是属性的代码:
public class ControllerAuthorize : AuthorizeAttribute
{
public ControllerAuthorize()
{
UnauthorizedAccessMessage = "You do not have the required access to view this content.";
}
//Property to allow array instead of single string.
private string[] _authorizedSources;
public string UnauthorizedAccessMessage { get; set; }
public string[] AuthorizedSources
{
get { return _authorizedSources ?? new string[0]; }
set { _authorizedSources = value; }
}
// return true if the IIS instance ID matches any of the AllowedSources.
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
throw new ArgumentNullException("httpContext");
//If no sources are supplied then return true, assuming none means any.
if (!AuthorizedSources.Any())
return true;
return AuthorizedSources.Any(ut => ut == httpContext.ApplicationInstance.Request.ServerVariables["INSTANCE_ID"]);
}
如果您想打开/关闭控制器并具有默认的捕获所有路由控制器,则该IHttpControllerActivator
实现不会禁用使用属性 routing 定义的路由。关闭 usingIHttpControllerActivator
会禁用控制器,但是当请求路由时,它不会命中所有路由控制器 - 它只是尝试命中已删除的控制器并返回未注册的控制器。