Несколько маршрутов веб-API не работает

Я строю пользовательский модуль для DNN 8.

Я построил модули с несколькими маршрутами, объявленными в классе контроллера. По какой-то причине с этим конкретным классом контроллера любые маршруты модулей, объявленные после первого, просто возвращают следующую ошибку:

Не найден ресурс HTTP, соответствующий URI запроса. На контроллере "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}, поэтому я убедился, что все маршруты имеют разные имена конечных параметров - DID NOT FIX
  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 (ветви, ранги, отдел) все возвращают сообщение об отсутствии действия... ошибка

Если я закомментирую места, тогда будут работать ветви, а остальные два - нет. Если я закомментирую местоположения и ветви, то ранги работают, но не последние.

Вот объявления маршрута от каждого класса:

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

Я знаю, что структура маршрута работает, потому что я получаю результаты

Очевидно, что здесь происходит какой-то конфликт, который я не могу найти. Контроллер получает удар, потому что маршруты созданы, но действие не может быть найдено по какой-то причине.

2 ответа

Решение

Причиной этого является то, что ваши маршруты фактически одинаковы, когда дело доходит до сопоставления с образцом.

Да, у вас другое имя в конце. Но если вы посмотрите на URL, который будет использоваться. Вы получаете что-то похожее на следующий сокращенный URL

Контроллер / Действие /My-branch Or Controller/ Действие /My-Department

Нет никакой возможности, чтобы система маршрутизации знала, что верхняя - это филиал, а нижняя - это отдел.

Типичная рекомендация - использовать только параметр id. В противном случае вам нужно будет изменить подпись. Возможно что-то вроде

{Контроллер}/{действие} / б /{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

Другие вопросы по тегам