0

我有一个我编写并发布的 ASP.NET Web API。既然它在那里,我们正在考虑做一些改进,这些改进涉及对某些调用的更改,这意味着我们需要版本来保持现有客户端的工作。

到目前为止,我在我的应用程序中使用了属性路由。方法由以下方式调用:Controller/Action 通过 RoutePrefix 和 Route 属性。

当我确实需要创建我的类的 V2 时,我只想重新创建实际更改的类,并将其他路由重定向回 v1 类,因为它们没有更改。(否则我最终会得到很多样板代码或重复代码)。

我想要做的是让以下路线适用于我的 v1 版本的类:Controller/Action

对于 V2,我希望任何新类都转到 V2,而任何未更改的类我想从 V1 类返回 HttpControllerDescriptor。路由看起来像 v2/Controller/Action,但会被重定向到 Controller/Action。

我已经实现了一个 IHttpControllerSelector 并返回了适当的 HttpControllerDescriptors 但它没有调用该方法。我相信这是因为路由信息与操作不匹配。(当我放入 IHttpActionSelector 并跟踪异常时,它说“找到了与请求匹配的多个操作)。

所以,我想我想知道:这甚至可能吗?这是实现我想要做的最好的方法吗?

4

1 回答 1

0

这是我在 asp.net web api 中实现的版本控制支持。需要注意的是,我没有使用属性路由,而是在 WebApiConfig.cs 中使用显式路由,因此如果您想遵循此模式,则需要切换回显式路由。此外,我不喜欢实际路由中的版本信息,我在 Accept 标头中使用自定义(即“版本”)参数。我还设置了每个 mime 类型的版本,如下例所示。如果客户端没有设置版本号或者请求的版本不存在,这将回退到默认控制器。

  1. 创建一个类并继承自,DefaultHttpControllerSelector以便您可以在需要时回退到基类行为。

  2. 覆盖SelectController方法如下:

    公共覆盖 HttpControllerDescriptor SelectController(HttpRequestMessage 请求) {

IDictionary 控制器 = GetControllerMapping(); IHttpRouteData routeData = request.GetRouteData();

                string controllerName = (string)routeData.Values["controller"];

                HttpControllerDescriptor controllerDescriptor;

                if (string.IsNullOrWhiteSpace(controllerName))
                {
                    return base.SelectController(request);
                }

                if (!controllers.TryGetValue(controllerName, out controllerDescriptor))
                {
                    return null;
                }

                string version = GetVersionFromAcceptHeader(request);
                if (string.Equals(version, "1"))
                {
                    return controllerDescriptor;
                }

                string newName = string.Concat(controllerName, "V", version);

                HttpControllerDescriptor versionedControllerDescriptor;
                if (controllers.TryGetValue(newName, out versionedControllerDescriptor))
                {
                    return versionedControllerDescriptor;
                }           

                return controllerDescriptor;
            }
  1. 在您的 webapiconfigRegister方法中注册此控制器选择器:

    config.Services.Replace(typeof(IHttpControllerSelector), new YourControllerSelector(config));

于 2017-08-28T08:19:54.463 回答