我有一个ASP.NET Web API(.NET 4)应用程序,它有一些控制器。我们将在IIS上运行Web API应用程序的多个实例,但有一点不同。某些IIS实例下只能使用某些控制器。我想的是在实例启动时禁用/卸载不适用于实例的控制器。
任何人都能获得一些可以指导我正确方向的信息吗?
答案 0 :(得分:3)
我认为不是卸载控制器,而是创建一个自定义的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"]);
}
答案 1 :(得分:3)
您可以通过装饰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());
<强>更新强>
自从我查看这个问题已经有一段时间了,但如果我今天要解决这个问题,我会稍微改变一下这个方法并使用自定义IHttpControllerSelector
。这在激活器之前被调用,并且使得启用和禁用控制器的位置稍微更有效......(尽管另一种方法确实有效)。您应该能够装饰或继承DefaultHttpControllerSelector
。
答案 2 :(得分:0)
IHttpControllerActivator
实现不会禁用使用属性路由定义的路由,如果要打开/关闭控制器并使用默认捕获所有路由控制器。使用IHttpControllerActivator
关闭会禁用控制器,但是当请求路由时,它不会捕获所有路由控制器 - 只是尝试命中已删除的控制器并且不返回已注册的控制器。