My personal preference here would be to pass the value as an HTTP header rather than a route parameter, especially if you want it everywhere. It means you don't need a Route attribute and a different URL per application. Using a custom ActionFilterAttribute, there's a bunch of ways you can pass this detail into your action. For example:
public class ApplicationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context.HttpContext.Request.Headers.TryGetValue("Application", out var values))
{
// Method 1: This allows you to specify a parameter on your action
context.ActionArguments.Add("application", values.First());
// Method 2: This adds the value into the route data
context.RouteData.Values.Add("Application", values.First());
// Method 3: This will set a property on your controller
if (context.Controller is BaseApplicationController baseController)
{
baseController.Application = values.First();
}
}
base.OnActionExecuting(context);
}
}
And apply it to action methods or your controller:
[Application]
public class FooController : Controller
{
}
Method 1 Usage:
public IActionResult Index(string application)
{
// do something with the parameter passed in
}
Method 2 Usage:
public IActionResult Index(string application)
{
var application = (string)RouteData.Values["Application"];
}
Method 3 Usage:
First, create a base controller that contains the property:
public abstract class BaseApplicationController : Controller
{
public string Application { get; set; }
}
Then make sure your controller inherits from it:
[Application]
public class FooController : BaseApplicationController
{
}
Now you can access the property on your controller:
public IActionResult Index(string application)
{
var application = this.Application;
}
Bonus Method 4:
As an aside, you could use this method to use the URL route value, using the base controller from method 3, modify the attribute to look like this:
public class ApplicationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context.Controller is BaseApplicationController baseController)
{
baseController.Application = (string)context.RouteData.Values["application"];
}
base.OnActionExecuting(context);
}
}
Add a route attribute to your controller:
[Route("{application}/api/[controller]/[action]")]
And now you should have the property value on the controller set.