Disable ApiController at Run Time

I have an ASP.NET Web API (.NET 4) application that has several controllers in it. We will be launching multiple instances of the Web API application in IIS with one difference. Only certain controllers will be available on specific IIS instances. What I was thinking about is disable / unload controllers that are not applicable to the instance when the instance starts.

Has anyone got some information that could help me in the right direction?

+7
source share
3 answers

You can host your own IHttpControllerActivator by decorating DefaultHttpControllerActivator. Inside, just check the configuration and only create a controller if allowed.

When you return null from the Create method, the user will receive a 404 Not Found message.

My example shows that the value in the application settings (App.Config or Web.Config) is checked, but, obviously, this can mean any other state of the environment.

 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); } } 

You can enable the activator like this:

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

Update

Some time has passed since I looked at this question, but if I decided to do this today, I would have changed the approach a bit and used the custom IHttpControllerSelector . This is called before the activator and makes a slightly more efficient place to enable and disable the controllers ... (although a different approach works). You must be able to decorate or inherit from DefaultHttpControllerSelector .

+3
source

Instead of unloading the controllers, I think I'm creating a special Authorize attribute that would look at the instance information, deciding to provide authorization.

You must add the following to each controller at the class level, or you can also add this to individual controller actions:

 [ControllerAuthorize (AuthorizedUserSources = new[] { "IISInstance1","IISInstance2","..." })] 

Here's the code for the attribute:

 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"]); } 
+2
source

The IHttpControllerActivator implementation IHttpControllerActivator not disable routes defined by attribute routing if you want to enable / disable the controller and use the entire route controller by default. Disabling with IHttpControllerActivator disables the controller, but when a route is requested, it does not fall on all catch route controllers - it simply tries to hit the remote controller and does not return the registered controller.

0
source

All Articles