【问题标题】:multiple web api routes not working多个 web api 路由不起作用
【发布时间】:2016-04-08 04:30:15
【问题描述】:

我正在为 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 ... 错误

如果我注释掉 locations,那么 branchs 将起作用,但其余两个不起作用。如果我注释掉 locationsbranchesranks 有效,但不是最后一个。

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

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

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

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

【问题讨论】:

  • 如果您将参数重命名为 ID 并仅映射单个路由 {controller}/{action}/{ID} 会发生什么?
  • @strickt01 没用。我仍在与此作斗争。

标签: asp.net vb.net asp.net-web-api dotnetnuke dotnetnuke-8


【解决方案1】:

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

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

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

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

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

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

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

【讨论】:

  • 感谢 Mitchel 的解释,我以为区分时会使用不同的动作方法名称,但我想不是。添加“d”或“b”或类似的东西就可以了。
【解决方案2】:

基本上 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

【讨论】:

    猜你喜欢
    • 2018-10-10
    • 2014-03-12
    • 2018-01-01
    • 2013-06-23
    • 1970-01-01
    • 2013-11-11
    • 2017-09-19
    • 1970-01-01
    • 2015-03-19
    相关资源
    最近更新 更多