问题:
有没有办法将两个不同的路由(带参数)分配给ASP.NET MVC 6应用程序中的同一个控制器?
我试过:
我尝试将多个路由属性用于控制器类以及单个操作,但是没有用。
备注:
我使用的是ASP.NET Core 1.0 RC1。
我想这样做的原因是,我希望api与使用旧网址的旧版移动应用兼容。
示例:
[Produces("application/json")]
[Route("api/v2/Log")]
/// The old route is "api/LogFile" which I want to be still valid for this controller.
public class LogController : Controller {
[HttpGet("{id}", Name = "download")]
public IActionResult GetFile([FromRoute] Guid id)
{
// ...
}
}
在上面的示例中:api/LogFile/{some-guid}
是旧路由,api/v2/log/download/{some-guid}
是新路由。我需要两个路由调用相同的动作。
答案 0 :(得分:47)
在控制器级别拥有2个路由属性在新的RC1应用程序中正常工作:
[Produces("application/json")]
[Route("api/[controller]")]
[Route("api/old-log")]
public class LogController: Controller
{
[HttpGet]
public IActionResult GetAll()
{
return Json(new { Foo = "bar" });
}
}
http://localhost:62058/api/log
和http://localhost:62058/api/old-log
都会返回预期的json。我见过的唯一警告是你可能想要设置属性的名称/顺序属性,以防你需要为其中一个动作生成url。
在动作上有2个属性也有效:
[Produces("application/json")]
public class LogController : Controller
{
[Route("api/old-log")]
[Route("api/[controller]")]
[HttpGet]
public IActionResult GetAll()
{
return Json(new { Foo = "bar" });
}
}
但是,在控制器级别和特定操作路径上使用常规路径时需要小心。在这些情况下,控制器级别的路由将用作前缀并添加到url之前(有一篇关于此行为的好文章here)。这可能会为您提供一组不同于您期望的网址,例如:
[Produces("application/json")]
[Route("api/[controller]")]
public class LogController : Controller
{
[Route("api/old-log")]
[Route("")]
[HttpGet]
public IActionResult GetAll()
{
return Json(new { Foo = "bar" });
}
}
在最后一种情况下,您的应用程序将侦听的2条路由将是http://localhost:62058/api/log
和http://localhost:62058/api/log/api/old-log
,因为api/log
被添加为在操作级别定义的所有路由的前缀。
最后,另一种选择是使用新路由的属性,然后使用启动类中的路由表来提供处理旧api的特定路由。