Disabling Controllers in .NET Core Web API with a Custom C# Attribute
In this article, we will discuss how to disable specific controllers in a .NET Core Web API application using a custom C# attribute. This can be useful when you have a generic base controller class that provides CRUD operations (GetAll, GetById, Insert, Update, Delete) and you want to exclude certain controllers from being accessible.
Creating a Custom Attribute
To achieve this, we need to create a custom attribute that will allow us to decorate the controllers we want to disable. This attribute will inherit from the Attribute class and override the IsDefined method.
public class DisableControllerAttribute : Attribute
{
public override bool IsDefined(MemberInfo member, bool inherit)
{
var type = member as Type;
if (type != null)
{
return type.GetCustomAttribute<DisableControllerAttribute>() != null;
}
return false;
}
}
]]>
</code>
<h3>Applying the Custom Attribute</h3>
<p>
Now that we have our custom attribute, we can apply it to the controllers we want to disable. Simply decorate the controller class with the <code>[DisableController]</code> attribute.
</p>
<code>
<![CDATA[
[DisableController]
public class DisabledController : GenericBaseController
{
// ...
}
]]>
</code>
<h3>Disabling Access to Controllers</h3>
<p>
To prevent access to the disabled controllers, we can create a middleware component that checks for our custom attribute and returns a <code>404 Not Found</code> response if the controller is disabled.
</p>
<code>
<![CDATA[
using System;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
public class DisableControllerMiddleware
{
private readonly RequestDelegate _next;
public DisableControllerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
var endpoint = context.GetEndpoint();
if (endpoint?.Metadata.Any(m => m is DisableControllerAttribute) == true)
{
context.Response.StatusCode = 404;
await context.Response.WriteAsync("Controller is disabled.");
return;
}
await _next(context);
}
}
]]>
</code>
<p>
Finally, we need to add our middleware to the application pipeline.
</p>
<code>
<![CDATA[
public void Configure(IApplicationBuilder app)
{
// ...
app.UseMiddleware<DisableControllerMiddleware>();
// ...
}
]]>
</code>
<ul>
<li><a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/attributes/">C# Attributes</a></li>
<li><a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters">ASP.NET Core Filters</a></li>
</ul>