多个网络 api 路由不工作

multiple web api routes not working

我正在为 DNN 8 构建自定义模块。

我构建了在控制器中声明了多个路由的模块 class。出于某种原因,对于这个特定的控制器 class,在第一个之后声明的任何模块路由只会 return 出现以下错误:

No HTTP resource was found that matches the request URI No action was found on the controller 'ServiceName' that matches the request.

如果我改变路线的顺序,第一个声明有效,但以下所有无效。

这个控制器 class 非常简单。这是:

    Public Class BranchServiceController
    Inherits DnnApiController
    Implements IServiceRouteMapper

    ''REGISTER SERIVCE ROUTES / URL
    Const moduleName As String = "ModuleName"

    Public Sub RegisterRoutes(routeManager As IMapRoute) Implements IServiceRouteMapper.RegisterRoutes

        routeManager.MapHttpRoute(moduleName,
                                  "branches",
                                  "{controller}/{action}/{DepID}",
                                  New String(){"ModuleName.Services.Controllers"})

        routeManager.MapHttpRoute(moduleName,
                                  "locations",
                                  "{controller}/{action}/{BranchID}",
                                  New String() {"ModuleName.Services.Controllers"})

    End Sub

    <HttpGet>
    <ActionName("locations")>
    <AllowAnonymous>
    Public Function GetLocation(BranchID As Int32) As List(Of BranchLocation)
        Try

            Dim locationCtl As New BranchLocationController

            ''get Branch based on supplied id
            Dim lBranch As List(Of BranchLocation) = locationCtl.GetBranchLocations(BranchID)

            Return lBranch

        Catch ex As Exception
            LogException(ex)
            Return Nothing
        End Try

    End Function

    <HttpGet>
    <ActionName("branches")>
    <AllowAnonymous>
    Public Function GetBranch(DepID As Int32) As List(Of Branch)
        Try

            Dim branchCtl As New BranchController

            ''get Branch based on supplied id
            Dim lBranch As List(Of Branch) = branchCtl.GetBranchs(DepID)

            Return lBranch

        Catch ex As Exception
            LogException(ex)
            Return Nothing
        End Try

    End Function

End Class

如果分支路线是第一个那么它会起作用,如果位置路线首先被声明它会起作用。我所做的只是复制和粘贴以更改顺序,所以我知道路线是准确的。

我以前从未遇到过这种情况。

我尝试了什么:

所以我将这些路线中的每一条分解成它们自己的 class。现在出现同样的问题。我能够在我的项目中向其他控制器 class 添加多个路由。这两条路线有些冲突。

我在 log4net 文件中看到路由被单独正确声明

2016-04-07 22:20:32,595 [][Thread:37][TRACE] DotNetNuke.Web.Api.Internal.ServicesRoutingManager - Mapping route: moduleName-locations-0 @ DesktopModules/moduleName/API/{controller}/{action}/{BranchID}
2016-04-07 22:20:32,598 [][Thread:37][TRACE] DotNetNuke.Web.Api.Internal.ServicesRoutingManager - Mapping route: moduleName-branches-0 @ DesktopModules/moduleName/API/{controller}/{action}/{DepID}

奇怪的是,如果我在单独的 class 中注释掉位置路线的 routeManager.MapHttpRoute,分支路线将起作用。

问题

有人能帮我弄清楚为什么在创建位置路由时这条分支路由不起作用吗?


编辑 1:

我尝试过的:

  1. 我认为可能有问题,因为我的操作名称 与 hte peta poco class 的名称匹配,该对象是 定义在。所以我将动作名称更改为随机名称 那没有解决它。
  2. 我想可能有问题 遵循相同模式的多条路线 {controller}/{action}/{DepID} 所以我确保所有路由都有 不同的结束参数名称 - 未修复
  3. 我确保路由和函数的参数名称匹配 - 这不是问题所在
  4. 我将每条路线都移到了它自己的控制器中 class 所以每条路线都有不同的 uri 控制器部分。没有修复

进一步的细节,我有一条路线总是有效 - 然后有四条路线无效。在这 4 条路线中,定义的第一条路线有效,但以下三个路线无效。我有一个记录路由创建的 log4net 日志:

2016-04-08 11:31:35,358  - Mapping route: KrisisShifts-locations-0 @ DesktopModules/KrisisShifts/API/{controller}/{action}/{BranchID}
2016-04-08 11:31:35,363  - Mapping route: KrisisShifts-branches-0 @ DesktopModules/KrisisShifts/API/{controller}/{action}/{DepartmentID}
2016-04-08 11:31:35,369  - Mapping route: KrisisShifts-ranks-0 @ DesktopModules/KrisisShifts/API/{controller}/{action}/{ID}
2016-04-08 11:31:35,373  - Mapping route: KrisisShifts-GetMonthCal-0 @ DesktopModules/KrisisShifts/API/{controller}/{action}/{CalID}/{DepID}/{MonthID}/{iYear}
2016-04-08 11:31:35,378  - Mapping route: KrisisShifts-department-0 @ DesktopModules/KrisisShifts/API/{controller}/{action}/{portalID}
2016-04-08 11:31:35,402  - Registered a total of 14 routes

GetMonthCal 路由每次都没有错误。位置 return 是一个结果,而其余 3 个( 分支机构、等级、部门 )全部 return 未找到任何操作。 ..错误

如果我注释掉 locations,那么 branches 将起作用,但其余两个将不起作用。如果我注释掉 locationsbranches 然后 ranks 工作但不是最后一个。

以下是每个 class:

的路由声明
        routeManager.MapHttpRoute(moduleName, "branches", "{controller}/{action}/{DepartmentID}", New String() {"Krisis.Modules.KrisisShifts.Services.Controllers"})
        routeManager.MapHttpRoute(moduleName, "GetMonthCal", "{controller}/{action}/{CalID}/{DepID}/{MonthID}/{iYear}", New String() {"Krisis.Modules.KrisisShifts.Services.Controllers"})
        routeManager.MapHttpRoute(moduleName, "department", "{controller}/{action}/{portalID}", New String() {"Krisis.Modules.KrisisShifts.Services.Controllers"})
        routeManager.MapHttpRoute(moduleName, "locations", "{controller}/{action}/{BranchID}", New String() {"Krisis.Modules.KrisisShifts.Services.Controllers"})
        routeManager.MapHttpRoute(moduleName, "ranks", "{controller}/{action}/{ID}", New String() {"Krisis.Modules.KrisisShifts.Services.Controllers"})

我知道路由结构在工作,因为我得到了结果

显然这里发生了某种我找不到的冲突。控制器被击中,因为路由已创建,但由于某种原因找不到操作。

这背后的原因是,在模式匹配方面,您的路由实际上是完全相同的。

是的,你最后出了一个不同的名字。但是,如果您查看将使用的 URL 。您会得到类似于以下缩写 URL

的内容

Controller/Action/My-branch 要么 Controller/Action/My-Department

路由系统不可能知道最上面的是分支机构,最下面的是部门。

典型的建议是只保留一个 id 参数。否则您将需要更改签名。可能类似于

{controller}/{action}/b/{branchName}

这将区分路线。然后您可以将部门的 /b 替换为 /d。

基本上 DNN 路线与 Asp.MVC 路线几乎相同。 所以如果你想指定你的控制器,你可以像这样让它静态化:

mapRouteManager.MapHttpRoute(
                moduleFolderName: "moduleFolder",
                routeName: "blablabla",
                url: "branches/{DepID}",
                defaults: new { controller = "BranchService", action = "GetBranch", DepID = RouteParameter.Optional },
                namespaces: new[] { "MyNamespace" }
            );

从 Url 开始,我可以直接调用它: http://../DesktopModules/moduleFolder/API/branches/1