I am building a custom module for DNN 8.
I have built modules with multiple routes declared in a controller class. For some reason with this particular controller class, any module routes declared after the first one just returns the following error:
No HTTP resource was found that matches the request URI No action was found on the controller 'ServiceName' that matches the request.
If I change the order of my routes, the first one declared works, but all the following ones do not.
This controller class is VERY simple. Here it is:
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
if the branches route is first then it works, if the locations route is declared first it works. All I am doing is copying and pasting to change the order so I know the routes are accurate.
I have never come across this before.
WHAT I TRIED:
So I broke each of these routes out into their own class. Now the same problem occurs. I was able to add multiple routes to other controller classes in my project. There is something about these two routes that are conflicting.
I can see in the log4net file that the routes are declared separately and correctly
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}
what is weird is if I comment out the routeManager.MapHttpRoute for the locations route in the separate class, the branches route will work.
Can someone help me figure out why this branches route won't work when the locations route is created?
What I have tried:
Further detail, I have one route that always works - and then four that do not. Of those 4, the first route that is defined works, but the following three do not. I have a log4net log that logs the route creation:
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
The GetMonthCal route works without error every time. Locations returns a result while the remaining 3 (branches, ranks, department) all return the no action found ... error
If I comment out locations, then branches will work but the remaining two will not. If i comment out locations and branches then ranks work but not the last one.
Here are the route declarations from each 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"})
I know that the route structure is working because I get results
There is obviously some kind of conflict going on here that I can not find. The controller is getting hit because the routes are created, but the action can not be found for some reason.
The reasoning behind this is that your routes are actuall all the same when it comes to pattern matching.
Yes, you out a different name at the end. But if you look at the URL that would be used. You get something similar to the following abbreviated URL
Controller/Action/My-branch Or Controller/Action/My-Department
There is no way that the routing system would know that the top one is a branch and that the bottom one is a department.
The typical recommendation is to keep with just an id parameter. Otherwise you will need to change the signature. Possibly something like
{controller}/{action}/b/{branchName}
That would differentiate the route. Then you could replace the /b with /d for department.