我正在使用mvc6制作一个版本化的API,为此我希望能够指定一个应该在哪个api版本上运行的动作。
我的api路由是:/api/{version}/...
所以我希望在某个操作中检查version
路由值并查看该操作是否适用于该版本。
我希望能够将其指定为api操作的属性,例如:
// This is the base api controller
[Route("api/{version:regex(^v[[0-9]].[[0-9]]$)}/[controller]")]
public abstract class ApiControllerBase { ... }
// This is an action in one of the sub classes
[HttpGet("foo")]
[ApiVersion("0.1", "0.2")] // Here! (this is params string[])
public object Foo()
{
// return
}
// This is an action in another sub class
[HttpGet("foo")]
[ApiVersion("1.0")]
public object Foo()
{
// return
}
我的问题是ApiVersion
应该为此实现或扩展的内容是什么?我不相信动作过滤器可以正常工作,因为当不匹配时我不想返回404,因为其他控制器中的其他操作可能能够处理这个(稍后我可能会HomeController
常见操作和Home2Controller
以及仅适用于1.0
)的扩展操作。
注意我不是要求ApiVersionAttribute
的实现,我只需要知道我应该挂钩的mvc基础设施(动作过滤器,路由约束,......)这将让我创建一个可以查看路线值的属性,并说明此操作是否匹配。
答案 0 :(得分:3)
花了4个小时分析mvc6来源,但这是值得的。我使用实现Microsoft.AspNet.Mvc.ActionConstraints.IActionConstraint
的操作属性解决了这个问题。
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class ApiVersionAttribute : Attribute, IActionConstraint
{
public ApiVersionAttribute(string version)
{
Version = version;
}
public string Version { get; }
public int Order => 0;
public bool Accept(ActionConstraintContext context)
{
var routeData = context.RouteContext.RouteData;
// return ...
}
}
然后是某个动作:
[HttpGet("foo")]
[ApiVersion("0.1")]
public object Foo()
{
// return ...
}