C# Web Api和版本控制器中的版本路由

C# Web Api和版本控制器中的版本路由,c#,asp.net-mvc,asp.net-web-api,C#,Asp.net Mvc,Asp.net Web Api,使用.NET4.5.2 我在Web Api中使用版本化路由 规范要求我们定义以下路线: /api/v1/成员/测试 /api/v2/成员/测试 下面的代码在版本1中找到了正确的方法 private static IEnumerable<VersionedRoute> GetRoutes(int version) { var routes = new List<VersionedRoute>(); if (version >=

使用.NET4.5.2

我在Web Api中使用版本化路由

规范要求我们定义以下路线:

/api/v1/成员/测试

/api/v2/成员/测试

下面的代码在版本1中找到了正确的方法

 private static IEnumerable<VersionedRoute> GetRoutes(int version)
    {
        var routes = new List<VersionedRoute>();
        if (version >= 1)
        {
            var versionedRoutes = new List<VersionedRoute>
            {
                new VersionedRoute(
                    version,
                    "Test",
                    "/Members/{id}/{action}",
                    new RouteValueDictionary
                    {
                        {"controller", "Members"},
                        {"action", "Test"},
                        {"id", RouteParameter.Optional}
                    })
            };

            routes.AddRange(versionedRoutes);
        }

        if (version >= 2)
        {
            var versionedRoutes = new List<VersionedRoute>{
                new VersionedRoute(
                    version,
                    "TestV2",
                    "/Members/{id}/{action}",
                    new RouteValueDictionary
                    {
                        {"controller", "MembersV2"},
                        {"action", "Test"},
                        {"id", RouteParameter.Optional}
                    }),
            };
            routes.AddRange(versionedRoutes);
        }

        return routes;
    }
但是,正如您所看到的,对于v2路由,我希望将请求定向到另一个控制器(MembersV2),在那里它将找到v2方法,但保持相同的路由公开。不幸的是,MembersV2没有被找到,因此当我向api/v2/members/test发送请求时,尽管找到了路由,但仍会调用members控制器并执行旧的v1方法

有什么我不明白的吗。有人能帮忙吗


如果我不清楚,请要求进一步澄清?

有多种方法可以进行API版本控制。你肯定不想重新发明轮子,因为它可能非常复杂

你可以阅读

在书的第57页,JamieKurtz解释了他是如何修改上述代码以满足新WebAPI2的需要的


我个人喜欢Jamie Kurtz的修改版,并在我的一些API中使用它

在这两种情况下定义的路由都是
“/Members/{id}/{action}”
,因此对
v2/Members/test
的请求与第一个v1路由的模板匹配(因为在匹配请求时路由定义的顺序很重要)

因此,您需要做的是使用如下显式版本定义路由:

private static IEnumerable<VersionedRoute> GetRoutes(int version)
{
    var routes = new List<VersionedRoute>();
    if (version >= 1)
    {
        var versionedRoutes = new List<VersionedRoute>
        {
            new VersionedRoute(
                version,
                "Test",
                "v1/Members/{id}/{action}",
                new RouteValueDictionary
                {
                    {"controller", "Members"},
                    {"action", "Test"}
                })
        };

        routes.AddRange(versionedRoutes);
    }

    if (version >= 2)
    {
        var versionedRoutes = new List<VersionedRoute>{
            new VersionedRoute(
                version,
                "TestV2",
                "v2/Members/{id}/{action}",
                new RouteValueDictionary
                {
                    {"controller", "MembersV2"},
                    {"action", "Test"}
                }),
        };
        routes.AddRange(versionedRoutes);
    }

    return routes;
}
私有静态IEnumerable GetRoutes(int版本)
{
var routes=新列表();
如果(版本>=1)
{
var versionedrootes=新列表
{
新多晶硅(
版本
“测试”,
“v1/Members/{id}/{action}”,
新RouteValueDictionary
{
{“控制器”、“成员”},
{“动作”、“测试”}
})
};
路线。添加范围(版本干旱);
}
如果(版本>=2)
{
var versionedrootes=新列表{
新多晶硅(
版本
“TestV2”,
“v2/Members/{id}/{action}”,
新RouteValueDictionary
{
{“控制器”,“成员2”},
{“动作”、“测试”}
}),
};
路线。添加范围(版本干旱);
}
返回路线;
}

应用程序就是这样做的,因此其他方法目前不在桌面上。如果能看到Jamie的修改版本会很方便,尽管我很欣赏这本书的版权。同上@Jeremythonpson——我知道即使是Skeeter也这么说,但到书的链接是另一个删除。在美国,合理使用至少应该允许对这里的建议进行很好的总结和演示,使其成为一个有用的答案。事实上,情况并非如此。(顺便说一句,我没有在上面看到。)对不起,路线应该是api/v2/members/testI更新了我的答案,但同样的原因仍然适用。我真的不明白你想做什么。此场景中的Id用于其他用途,而不是用于版本控制]
private static IEnumerable<VersionedRoute> GetRoutes(int version)
{
    var routes = new List<VersionedRoute>();
    if (version >= 1)
    {
        var versionedRoutes = new List<VersionedRoute>
        {
            new VersionedRoute(
                version,
                "Test",
                "v1/Members/{id}/{action}",
                new RouteValueDictionary
                {
                    {"controller", "Members"},
                    {"action", "Test"}
                })
        };

        routes.AddRange(versionedRoutes);
    }

    if (version >= 2)
    {
        var versionedRoutes = new List<VersionedRoute>{
            new VersionedRoute(
                version,
                "TestV2",
                "v2/Members/{id}/{action}",
                new RouteValueDictionary
                {
                    {"controller", "MembersV2"},
                    {"action", "Test"}
                }),
        };
        routes.AddRange(versionedRoutes);
    }

    return routes;
}