我个人的偏好是将值作为 HTTP 标头而不是路由参数传递,特别是如果您希望它无处不在。这意味着您不需要 Route 属性和每个应用程序的不同 URL。使用自定义ActionFilterAttribute,您可以通过多种方式将此详细信息传递到您的操作中。例如:
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);
}
}
并将其应用于操作方法或您的控制器:
[Application]
public class FooController : Controller
{
}
方法一用法:
public IActionResult Index(string application)
{
// do something with the parameter passed in
}
方法二用法:
public IActionResult Index(string application)
{
var application = (string)RouteData.Values["Application"];
}
方法三用法:
首先,创建一个包含该属性的基本控制器:
public abstract class BaseApplicationController : Controller
{
public string Application { get; set; }
}
然后确保你的控制器继承自它:
[Application]
public class FooController : BaseApplicationController
{
}
现在您可以访问控制器上的属性:
public IActionResult Index(string application)
{
var application = this.Application;
}
奖励方法4:
顺便说一句,您可以使用此方法来使用 URL 路由值,使用方法 3 中的基本控制器,将属性修改为如下所示:
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);
}
}
为你的控制器添加路由属性:
[Route("{application}/api/[controller]/[action]")]
现在您应该在控制器集上设置了属性值。