我遇到了 API 版本控制 (ASP.NET Core API 2.1) 的问题。我试图取代现有控制器的一种方法,而不必复制以前版本中的所有方法。我认为这会起作用,但它给我带来了路由冲突的问题。例子:
namespace MyApi.Controllers
{
[Produces("application/json")]
[Route("api/v{version:apiVersion}")]
public class BaseController : Controller
{
public string VersionNumber => GetRouteValue<string>(ControllerContext, "version");
protected static TValue GetRouteValue<TValue>(ControllerContext context, string name)
{
return (TValue)Convert.ChangeType(context.RouteData.Values[name], typeof(TValue));
}
}
}
namespace MyApi.Controllers
{
[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class ValuesController : BaseController
{
[HttpGet("values", Name = "GetValuesV1.0")]
public IActionResult GetValues() => Ok(new string[] { "value 1", "value 2" });
[HttpGet("values/{value}", Name = "GetValueV1.0")]
public IActionResult GetValue(string value) => Ok( value });
}
}
namespace MyApi.Controllers.V2_0
{
[ApiVersion("2.0")]
public class ValuesController : BaseController
{
[HttpGet("values", Name = "GetValuesV2.0")]
public IActionResult GetValues() => Ok(new string[] { "value 1", "value 2", "value 3" });
}
}
然后我得到错误:
路径 'xxx' 上的方法 'Get' 被多次注册。
我想在两个版本中都支持 GetValue(string value) 方法,但我不想在每次版本时都复制新控制器中的代码。我只想替换一种方法。这是可能的,还是我必须复制整个以前的控制器和其中的每个方法?这有效,但感觉很糟糕:
namespace MyApi.Controllers
{
[Produces("application/json")]
[Route("api/v{version:apiVersion}")]
public class BaseController : Controller
{
public string VersionNumber => GetRouteValue<string>(ControllerContext, "version");
protected static TValue GetRouteValue<TValue>(ControllerContext context, string name)
{
return (TValue)Convert.ChangeType(context.RouteData.Values[name], typeof(TValue));
}
}
}
namespace MyApi.Controllers
{
[ApiVersion("1.0")]
public class ValuesController : BaseController
{
[HttpGet("values", Name = "GetValuesV1.0")]
public IActionResult GetValues() => Ok(new string[] { "value 1", "value 2" });
[HttpGet("values/{value}", Name = "GetValueV1.0")]
public IActionResult GetValue(string value) => Ok( value });
}
}
namespace MyApi.Controllers.V2_0
{
[ApiVersion("2.0")]
public class ValuesController : BaseController
{
[HttpGet("values", Name = "GetValuesV2.0")]
public IActionResult GetValues() => Ok(new string[] { "value 1", "value 2", "value 3" });
[HttpGet("values/{value}", Name = "GetValueV2.0")]
public IActionResult GetValue(string value) => Ok( value });
}
}
这现在有效,但我只是无缘无故地复制了代码。在有大量代码的控制器中,这感觉就像代码异味。有解决方法吗?