VahidDev
VahidDev

Reputation: 31

Dynamically Change Routing in ASP.NET 6.0 Web API

I want to take an environmental variable and prefix it to the route for all the controllers. So in Controllers I have the followings:

[ApiController]
[Route("[controller]")]
public class DashboardsController : ControllerBase
{.......}

Program.cs routing part ==>

app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.Run();

I have tried creating a class with constant strings and putting into the Route attribute but as you know we cannot change constants, so this didn't work.

Upvotes: 2

Views: 2144

Answers (2)

VahidDev
VahidDev

Reputation: 31

After @julealgon's answer, this is the final solution.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
    public sealed class DynamicRouteAttribute : RouteAttribute
    {
        public DynamicRouteAttribute(string template) 
            : base($"{Environment.GetEnvironmentVariable("test")}/{template}")
        {
            ArgumentNullException.ThrowIfNull(template);
        }
    }

Upvotes: 0

julealgon
julealgon

Reputation: 8221

The [Route] attribute implements a IRouteTemplateProvider interface, which defines a Template property that returns the route template.

If you implement a custom attribute, say [DynamicRoute], that takes an environment variable name as a parameter, you could set the Template property to a different value based on the environment variable passed in.

This works for me:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
    public sealed class DynamicRouteAttribute : Attribute, IRouteTemplateProvider
    {
        public DynamicRouteAttribute(string environmentVariableName)
        {
            ArgumentNullException.ThrowIfNull(environmentVariableName);

            Template = Environment.GetEnvironmentVariable(environmentVariableName);
        }

        public string? Template { get; }

        public int? Order { get; set; }

        public string? Name { get; set; }
    }

Replace [Route("[controller]")] in your controller with [DynamicRoute("yourEnvVarName")] and it will start to honor whatever you configure in your environment variable.

Upvotes: 1

Related Questions