9

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

任何人都可以获得一些可以指导我正确方向的信息吗?

4

3 回答 3

5

您可以通过装饰 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.

于 2012-11-21T10:25:07.820 回答
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"]);
    }
于 2012-11-21T01:19:48.490 回答
0

如果您想打开/关闭控制器并具有默认的捕获所有路由控制器,则该IHttpControllerActivator实现不会禁用使用属性 routing 定义的路由。关闭 usingIHttpControllerActivator会禁用控制器,但是当请求路由时,它不会命中所有路由控制器 - 它只是尝试命中已删除的控制器并返回未注册的控制器。

于 2016-11-11T08:50:15.640 回答