C# WebApi–;控制器继承–;方法的新版本
我使用WebAPI2。我在version1中提供客户机方法:C# WebApi–;控制器继承–;方法的新版本,c#,asp.net-mvc,asp.net-web-api,asp.net-mvc-routing,asp.net-web-api-routing,C#,Asp.net Mvc,Asp.net Web Api,Asp.net Mvc Routing,Asp.net Web Api Routing,我使用WebAPI2。我在version1中提供客户机方法: http://localhost/version1/api/base http://localhost/version1/api/values 它是地雷控制员: [RoutePrefix("version1")] public class ValuesController : ApiController { [Route("api/base")] public string GetBaseMethod()
http://localhost/version1/api/base
http://localhost/version1/api/values
它是地雷控制员:
[RoutePrefix("version1")]
public class ValuesController : ApiController
{
[Route("api/base")]
public string GetBaseMethod()
{
return "bbb";
}
[Route("api/values")]
public string GetVersion1()
{
return "aaa";
}
}
现在,我想以version2方法提供客户机:
- /version2/api/base(方法与version1相同)
- /version2/api/values(方法已更改,现在它返回int,而不是string,但地址必须与version1:/api/values中的地址相同)
[RoutePrefix("version2")]
public class Values2Controller : ValuesController
{
[Route("api/values")]
public int GetVersion2()
{
return 5;
}
}
我已在WebApiConfig.cs中启用属性路由继承:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes(new CustomDirectRouteProvider());
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
public class CustomDirectRouteProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList<IDirectRouteFactory> GetActionRouteFactories(HttpActionDescriptor actionDescriptor)
{
return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>(inherit: true);
}
}
公共静态类WebApiConfig
{
公共静态无效寄存器(HttpConfiguration配置)
{
config.maphttpAttribute路由(新的CustomDirectRouteProvider());
config.Routes.MapHttpRoute(
名称:“DefaultApi”,
routeTemplate:“api/{controller}/{id}”,
默认值:新建{id=RouteParameter.Optional}
);
}
}
公共类CustomDirectRouteProvider:DefaultDirectRouteProvider
{
受保护的重写IReadOnlyList GetActionRouteFactorys(HttpActionDescriptor actionDescriptor)
{
返回actionDescriptor.GetCustomAttributes(继承:true);
}
}
结果:
http://localhost/version1/api/base
- 它起作用了
http://localhost/version2/api/base
- 它起作用了
http://localhost/version1/api/values
- 它起作用了
http://localhost/version2/api/values
- 它不起作用。我有错误:
我相信这是同样的问题。您需要“api/{controller}/{action}/{id}”我可以重新创建您的问题。只有当我将原始的GetVersion1虚拟化,将返回类型更改为更一般的对象,然后在继承的类中重写它时,我才能使用不同的变体 像这样:
[RoutePrefix("version1")]
public class ValuesController : ApiController {
[Route("api/base")]
public string GetBaseMethod() {
return "bbb";
}
[Route("api/values")]
public virtual object GetVersion1() {
return "aaa";
}
}
[RoutePrefix("version2")]
public class Values2Controller : ValuesController {
public override object GetVersion1() {
return 5;
}
}
一旦存在冲突的路由属性并启用了路由继承,它就会像您所指出的那样失败
这让我思考。如果您打算使用继承,那么为什么不将其作为路由处理呢。因此,我最终决定以您的例子为例:
这将允许我在将来的版本中更改基础返回值,而不会发生路由冲突
结果:
http://localhost/version1/api/base
- 它有效。=>“bbb”
http://localhost/version2/api/base
- 它有效。=>“bbb”
http://localhost/version1/api/values
- 它有效。=>“aaa”
http://localhost/version2/api/values
- 它有效。=>五,
Route
属性,在实现基类的类中再次指定它会导致冲突。还需要注意的是,您只在基类的虚拟方法上指定Route
属性。在重写它们的类上指定它们会导致冲突。如何停止从version2访问GetBaseMethod?我想让用户知道此方法在version2上不可用。
[RoutePrefix("version1")]
public class ValuesController : ApiController {
[Route("api/base")]
public virtual HttpResponseMessage GetBaseMethod() {
return Request.CreateResponse("bbb");
}
[Route("api/values")]
public virtual HttpResponseMessage GetVersion1() {
return Request.CreateResponse("aaa");
}
}
[RoutePrefix("version2")]
public class Values2Controller : ValuesController {
public override HttpResponseMessage GetVersion1() {
return Request.CreateResponse(5);
}
}