我使用Web API 2.我在版本1中提供客户端方法:
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";
}
}
现在我想以版本2方法提供客户端:
所以我有第二个带继承的控制器:
[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);
}
}
结果:
http://localhost/version1/api/base
http://localhost/version2/api/base
http://localhost/version1/api/values
http://localhost/version2/api/values
{ &#34;消息&#34;:&#34;发生了错误。&#34;, &#34; ExceptionMessage&#34;:&#34;找到与请求匹配的多个操作:\ r \ n \ nGetVersion2 on type 类型上的WebApplication1.Controllers.Values2Controller \ r \ n \ nGetVersion1 WebApplication1.Controllers.Values2Controller&#34 ;, &#34; ExceptionType&#34;:&#34; System.InvalidOperationException&#34;, &#34; StackTrace&#34;:&#34; w System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)\ r \ n w System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)\ r \ n w System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext,CancellationToken cancellationToken)\ r \ n w System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()&#34; }
我该怎么办?
答案 0 :(得分:2)
我能够重现你的问题。使用不同的变体我只能在原始的 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;
}
}
一旦启用了冲突的Route属性和路由继承,它就会失败,就像你指示的那样。
这让我思考。如果您要使用继承,那么为什么不仅仅使用路由来处理它。所以我最终根据你的例子确定了以下内容:
[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);
}
}
这将允许我在没有路由冲突的情况下更改未来版本中的基础返回值。
结果:
http://localhost/version1/api/base
http://localhost/version2/api/base
http://localhost/version1/api/values
http://localhost/version2/api/values
答案 1 :(得分:0)
Multiple actions were found that match the request: webapi
我相信这是同样的问题。您需要&#34; api / {controller} / {action} / {id}&#34;