ASP.NET 整个控制器中可用的核心路由属性 class

ASP.NET Core Route attributes available in entire controller class

有没有办法让路由中指定的属性在整个class中可用?例如,考虑这个控制器:

[Route("api/store/{storeId}/[controller]")]
public class BookController
{
    [HttpGet("{id:int:min(1)}")]
    public async Task<IActionResult> GetBookById(int storeId, int id)
    {
    }
}

而这个请求:

/api/store/4/book/1

在 GetBookById 方法中,storeId 变量正确填充为 4,id 变量正确填充为 1。但是,不必在 BookController 的每个方法中传递 storeId 变量,有没有办法做类似的事情这个:

[Route("api/store/{storeId}/[controller]")]
public class BookController
{
    private int storeId;

    [HttpGet("{id:int:min(1)}")]
    public async Task<IActionResult> GetBookById(int id)
    {
        //use value of storeId here
    }
}

如果控制器继承自Controller class那么你可以覆盖OnActionExecuting方法,如果控制器继承自ControllerBase你需要实现IActionFilter使其工作的界面

[Route("api/store/{storeId}/[controller]")]
public class BookController : ControllerBase, IActionFilter
{
    private int storeId;

    [HttpGet("{id:int:min(1)}")]
    public async Task<IActionResult> GetBookById(int id)
    {
        // use value of storeId here
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        //empty
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        string value = context.RouteData.Values["storeId"].ToString();
        int.TryParse(value, out storeId);
    }
}

或者使用控制器 属性 上的 [FromRoute] 属性对此有更好的解决方案(如所述

[Route("api/store/{storeId}/[controller]")]
public class BookController : ControllerBase
{
    [FromRoute(Name = "storeId")] 
    public int StoreId { get; set; }

    [HttpGet("{id:int:min(1)}")]
    public async Task<IActionResult> GetBookById(int id)
    {
        // use value of storeId here
    }       
}