1

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

我已经构建了具有在控制器类中声明的多个路由的模块。出于某种原因,对于这个特定的控制器类,在第一个之后声明的任何模块路由都只会返回以下错误:

未找到与请求 URI 匹配的 HTTP 资源 在控制器“ServiceName”上未找到与请求匹配的操作。

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

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

    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

如果首先声明了分支路线,则它可以工作,如果首先声明了位置路线,则它可以工作。我所做的只是复制和粘贴以更改顺序,因此我知道路线是准确的。

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

我尝试了什么:

因此,我将这些路线中的每一条都分成了自己的班级。现在出现了同样的问题。我能够在我的项目中向其他控制器类添加多个路由。这两条路线有些冲突。

我可以在 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}

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

问题

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


编辑1:

我试过的:

  1. 我认为可能存在问题,因为我的操作名称与定义对象的 hte peta poco 类的名称匹配。所以我将操作名称更改为随机名称,但没有修复它。
  2. 我想可能有多个路由遵循与 {controller}/{action}/{DepID} 相同的模式存在问题,所以我确保所有路由都有不同的结束参数名称 - 未修复
  3. 我确保路由和函数的参数名称匹配 - 这不是问题
  4. 我将每条路由都移到了它自己的 Controller 类中,因此每条路由都有不同的 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 路线每次都能正常工作。Locations 返回一个结果,而其余 3 个(分支、排名、部门)都返回no action found ...错误

如果我注释掉位置,那么分支会起作用,但其余两个不会。如果我注释掉位置分支然后排名工作,但不是最后一个。

以下是每个类的路由声明:

        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"})

我知道路线结构有效,因为我得到了结果

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

4

2 回答 2

2

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

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

控制器/操作/我的分支或控制器/操作/我的部门

路由系统不可能知道顶部是一个分支,底部是一个部门。

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

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

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

于 2016-04-09T12:24:24.133 回答
0

基本上 DNN 路由与 Asp.MVC 路由几乎相同。因此,如果您想指定您的控制器,您可以将其设为静态,如下所示:

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

从网址,我可以称之为: http://../DesktopModules/moduleFolder/API/branches/1

于 2016-04-10T16:32:38.470 回答