16

Let's say that I have a ASP.NET application that have some APIs.

For example,

{HostName}/api/a/*      
{HostName}/api/b/*

Now I want to disable all {HostName}/api/a/* APIs(But remain /api/b/*). When client call /api/a/* APIs, they get a 404 error. When client call /api/b/* APIs, response normally.

Is there any way to do this in c# ASP.NET application?

7
  • 3
    delete them in the code? Commented Aug 17, 2016 at 8:27
  • You can implement something like DisableFunctionalityActionFilter and assign it to a controller / area / action, which must be disabled. Commented Aug 17, 2016 at 8:28
  • Just change name of controller name to something meaningless. Commented Aug 17, 2016 at 8:29
  • 1
    are you looking for NonAction attribute? To prevent a method from getting invoked as an action, use the NonAction attribute. This signals to the framework that the method is not an action, even if it would otherwise match the routing rules. Commented Aug 17, 2016 at 8:29
  • As there are so many APIs I want to disable, and the disable action might be just temporary(might re-enable some day), delete them in code or add an attribute to each function seems too many work to do... Commented Aug 17, 2016 at 8:39

3 Answers 3

34

There are several approaches a can take to disable certain actions or routes as mentioned in the comments.

1.) [NonAction] attribute

The [NonAction] attribute from System.Web.Http can be applied for ApiController actions. If such a method is called then the server returns the HTTP Code 404 (Method not found). The attribute can only be applied on method level and not on classes. So every single method has to be decorated with this attribute.

2.) Writing a custom action filter

This approach gives you more control. Your filter can be applied on class level and you can implement some more advanced logic in which conditions your controller is accessible or not (depending on dates, licences, feature toggles and so forth)

public class MyNoActionFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {            
        if (IfDisabledLogic(actionContext))
        {
            actionContext.Response = new HttpResponseMessage(HttpStatusCode.NotFound);
        }
        else                
          base.OnActionExecuting(actionContext);
    }
}

[MyNoActionFilter]
public class ValuesController : ApiController
{
    // web api controller logic...
}

3.) Route Configuration in WebApiConfig.cs

You can add a web api route for the inaccessible controllers in the WebApiConfig and map this route to a non existant controller. Then the framework takes this route, does not find the controller and sends a 404 return code to the client. It is important to place these routes at the beginning in order to avoid undesired execution.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        
        config.Routes.MapHttpRoute(
            name: "DisabledApi",
            routeTemplate: "api/b/{id}",
            defaults: new { controller = "DoesNotExist", id = RouteParameter.Optional }
        );

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

Because you stated not to use attributes because of the amount of work I recommend the third option, because the route configuration defines a single place for this. And if you want to enable the route in the future again you have to remove only one route definition.

Sign up to request clarification or add additional context in comments.

1 Comment

For approach number 2 in Net Core, instead of setting actionContext.Response you should set actionContext.Result so that it returns immediately; i.e: actionContext.Result = new NotFoundObjectResult(actionContext.ModelState);
6

Might be a hack, but works fine for me:

Changing scope of the Controller from public to internal hides all actions from that Controller class. So:

internal class AController : ApiController
{
  [...]
}

Requests to http://host/api/a/* then will fail with "No type was found that matches the controller named 'a'."

Comments

6

Feature flags were built for this purpose

How to enable/disable controllers/routes using feature flags: Tutorial for using feature flags in a .NET Core app | Microsoft Docs

To enable this in your app:

  1. Add the Microsoft.FeatureManagement.AspNetCore nuget package to your project.

  2. Add the feature management service to your builder in Program.cs: builder.Services.AddFeatureManagement();

  3. Add settings for the features you want to turn on and off in appsettings.json:

     { "FeatureManagement": {    
       "AdminAccess": true, 
       "AnonymousAccess": false 
     }
    
  4. Add the FeatureGate decorator to the controllers/actions you want to control access to: [FeatureGate("AnonymousAccess")]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.