为了账号安全,请及时绑定邮箱和手机立即绑定

具有继承性的 Web API 版本控制

具有继承性的 Web API 版本控制

C#
陪伴而非守候 2021-08-07 17:42:18
我试图让 Web API 版本控制与继承的类一起工作。我正在使用股票Values控制器的两个非常简单的变体。[ApiVersion("1.0")][RoutePrefix("api/v{version:apiVersion}/Values")][ControllerName("Values")]public class ValuesController : ApiController{    // GET api/values    [Route("")]    public IEnumerable<string> Get()    {        return new string[] { "value1", "value2" };    }    // GET api/values/5    [Route("{id:int}")]    public virtual string Get(int id)    {        return "value from 1";    }}[ApiVersion("2.0")][RoutePrefix("api/v{version:apiVersion}/Values")][ControllerName("Values")]public class Values2Controller : ValuesController{    //Want to use the method in the base class    //public IEnumerable<string> Get()    //{    //    return new string[] { "value2-1", "value2-2" };    // }    [Route("{id:int}")]    // GET api/values/5    public new string Get(int id)    {        return "value from 2";    }} 我的启动配置也非常简单。public static void Register(HttpConfiguration config){    var constraintResolver = new DefaultInlineConstraintResolver()    {        ConstraintMap = {["apiVersion"] = typeof(ApiVersionRouteConstraint)}    };    config.MapHttpAttributeRoutes(constraintResolver);    config.AddApiVersioning(o => { o.AssumeDefaultVersionWhenUnspecified = true; });}未覆盖的路由完全按照我的预期工作 http://localhost:32623/api/v1.0/Values/12->“来自 1 的值” http://localhost:32623/api/v2.0/Values/12->“来自 2 的值”调用默认Get路由的 v1 http://localhost:32623/api/v1.0/Values -> Value1, Value2但是在子控制器上尝试相同的路由会导致错误。http://localhost:32623/api/v2.0/Values<Message>The HTTP resource that matches the request URI 'http://localhost:32623/api/v2.0/Values' does not support the API version '2.0'.</Message><InnerError><Message>No route providing a controller name with API version '2.0' was found to match request URI 'http://localhost:32623/api/v2.0/Values'.</Message></InnerError>错误消息表明被覆盖的成员需要“1.0”路由,我可以在子类中使用这样的方法解决这个问题。[Route("")]public override IEnumerable<string> Get(){    return base.Get();}但这在更大的应用程序中似乎不太理想。有没有办法让这项工作按照我想要的方式工作,没有这些“空”覆盖?
查看完整描述

1 回答

?
喵喵时光机

TA贡献1846条经验 获得超7个赞

您需要做的是覆盖DefaultDirectRoutePrivider以允许路由继承:


public class WebApiCustomDirectRouteProvider : DefaultDirectRouteProvider {

    protected override IReadOnlyList<IDirectRouteFactory>

        GetActionRouteFactories(HttpActionDescriptor actionDescriptor) {

        // inherit route attributes decorated on base class controller's actions

        return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>(inherit: true);

    }

}

完成后,您将需要在您的 web api 配置中配置它以及自定义路由约束


public static void Register(HttpConfiguration config) {

    var constraintResolver = new DefaultInlineConstraintResolver() {

        ConstraintMap = {["apiVersion"] = typeof(ApiVersionRouteConstraint)}

    };

    var directRouteProvider = new WebApiCustomDirectRouteProvider();

    // Attribute routing. (with inheritance)

    config.MapHttpAttributeRoutes(constraintResolver, directRouteProvider);

    config.AddApiVersioning(_ => { _.AssumeDefaultVersionWhenUnspecified = true; });

}

所以现在继承值控制器现在将具有派生控制器中可用的基本路由


用于演示目的


[ApiVersion("1.0")]

[RoutePrefix("api/v{version:apiVersion}/Values")]

[ControllerName("Values")]

public class ValuesController : ApiController {


    [HttpGet]

    [Route("")] // GET api/v1.0/values

    public virtual IHttpActionResult Get() {

        return Ok(new string[] { "value1", "value2" });

    }


    [HttpGet]

    [Route("{id:int}")] // GET api/v1.0/values/5

    public virtual IHttpActionResult Get(int id) {

        return Ok("value from 1");

    }

}


[ApiVersion("2.0")]

[RoutePrefix("api/v{version:apiVersion}/Values")]

[ControllerName("Values")]

public class Values2Controller : ValuesController {


    //Will have inherited GET "api/v2.0/Values" route


    // GET api/v2.0/values/5 (Route also inherited from base controller)

    public override IHttpActionResult Get(int id) {

        return Ok("value from 2");

    }

您会注意到子级中的路由并未用于覆盖的操作,因为它也将从基本控制器继承。


查看完整回答
反对 回复 2021-08-07
  • 1 回答
  • 0 关注
  • 180 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信