20

What is the best way to disable ASP.NET MVC controller conditionally?

I want to have an access to the controller actions if some value in web.config is "true" and 404 if it's "false"

Should I write my own attribute?

UPDATE: Looking for more elegant solution than action filter attribute (with an ability to pass not constant parameter to attribute constructor)

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public class CloseForSomeSettingAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            bool mySettingValue = MySettingManager.GetMySettingValue();

            if (mySettingValue)
            {
                filterContext.Result = new HttpStatusCodeResult(404);
            }
            else
            {
                base.OnActionExecuting(filterContext);
            }
        }
    }
Dmitry Khryukin
  • 6,408
  • 7
  • 36
  • 58

3 Answers3

6

The easiest would probably be to implement a custom action filter:

http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/understanding-action-filters-cs

You can also conditionally add a route that matches that controller that would result in a 404 being returned.

igz168
  • 94
  • 2
  • thanks. have written the action filter attribute (see my comment). but maybe some more elegant solution exists? – Dmitry Khryukin Jul 23 '12 at 01:16
  • I don't know your purpose here but perhaps it's best not to do this at the application level? I'm thinking using IIS url-rewrite module to setup rules for the routes you're looking to return 404. Take a look at the examples below:http://blogs.iis.net/ruslany/archive/2009/04/08/10-url-rewriting-tips-and-tricks.aspx – igz168 Jul 23 '12 at 02:23
  • no. I need to have an ability to switch it from a web.config file. – Dmitry Khryukin Jul 23 '12 at 02:26
  • 1
    the rules for url-rewrite are stored in the web.config – igz168 Jul 23 '12 at 03:00
3

Answered here - Prevent ASP.NET Core discovering Controller in separate assembly

This approach doesn't need filters, and hides controller from swagger etc.

David McEleney
  • 3,397
  • 1
  • 26
  • 32
0

Cross posting from: https://stackoverflow.com/a/43044667/257470

My solution for disabling ApiController controller:

  • Uses WebConfig AppSettings config flag instead of (#if DEBUG)
  • Before method is invoked ExecuteAsync intercepts the invocation and checks feature toggle (feature flag);
  • if feature is disabled, returns HTTP 410 GONE
  • If it's common for many controllers, move the code to controller's base class

The code:

public class TestController : ApiController
{
    public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
    {
        var featureFlag = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["EnableTest"]);

        if (featureFlag == false)
        {
            return Task.FromResult(new HttpResponseMessage(HttpStatusCode.Gone));
        }

        return base.ExecuteAsync(controllerContext, cancellationToken);
    }
Community
  • 1
  • 1
andrew.fox
  • 7,435
  • 5
  • 52
  • 75