DNN 7 Получение ошибки String.Replace Null при вызове NavigateUrl — AdvancedFriendlyUrlProvider

У меня есть собственный модуль, который я разрабатываю на платформе 7.3.4. У меня есть ModuleSearchBase, работающий в моей установке для разработки, где я переопределяю функцию GetModifiedSearchDocuments для создания поисковых документов для модуля.

Проблема возникает, когда я устанавливаю этот модуль в «живую» установку dnn.

Вот трассировка стека, которая регистрируется при запуске запланированного события индекса поиска:

DefaultDataProvider:DotNetNuke.Data.SqlDataProvider, DotNetNuke
ExceptionGUID:72337bbc-1a23-4103-bad9-70cbdb0e907d
InnerException:Value cannot be null. Parameter name: oldValue
FileName:
FileLineNumber:0
FileColumnNumber:0
Method:System.String.Replace
StackTrace:
Message:
System.ArgumentNullException: Value cannot be null.
Parameter name: oldValue
   at System.String.Replace(String oldValue, String newValue)
   at DotNetNuke.Entities.Urls.AdvancedFriendlyUrlProvider.GetFriendlyAlias(String path, String& httpAlias, Int32 portalId, FriendlyUrlSettings settings, PortalSettings portalSettings, Boolean& cultureSpecificAlias)
   at DotNetNuke.Entities.Urls.AdvancedFriendlyUrlProvider.FriendlyUrlInternal(TabInfo tab, String path, String pageName, String portalAlias, PortalSettings portalSettings)
   at DotNetNuke.Entities.Urls.AdvancedFriendlyUrlProvider.FriendlyUrl(TabInfo tab, String path, String pageName, PortalSettings portalSettings)
   at DotNetNuke.Services.Url.FriendlyUrl.DNNFriendlyUrlProvider.FriendlyUrl(TabInfo tab, String path, String pageName, PortalSettings settings)
   at DotNetNuke.Common.Globals.NavigateURL(Int32 tabID, Boolean isSuperTab, PortalSettings settings, String controlKey, String language, String pageName, String[] additionalParameters)
   at DotNetNuke.Common.Globals.NavigateURL(Int32 tabID, Boolean isSuperTab, PortalSettings settings, String controlKey, String language, String[] additionalParameters)
   at Krisis.Modules.KrisisStore.Components.FeatureController.GetModifiedSearchDocuments(ModuleInfo moduleInfo, DateTime beginDate)

Что я пробовал:

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

  2. Я попытался добавить в средство просмотра событий запись через точку останова VIA, чтобы увидеть, как далеко будет выполняться мой код, прежде чем эта ошибка будет выдана. Это позволило мне сузить ошибку до следующей строки:

                    objEventLog.AddLog("BREAK 2", " break 2 " + ModID.ToString, pSettings, -1, DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.ADMIN_ALERT)
    
                    Dim DetailUrl = NavigateURL(moduleInfo.TabID, pSettings, "Detail", array)
    
                    objEventLog.AddLog("BREAK 3", "DetailUrl = " + DetailUrl, pSettings, -1, DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.ADMIN_ALERT)
    

Вы можете увидеть «точки останова» в функции objEventLog.AddLog. Точка останова 2 сработала, а точка останова 3 — нет. Не работает код функции NaviagteURL.

Я подтвердил, что значение tabId не равно нулю, и это точный код, который я использую в службе web.api в модуле, и он отлично работает. Кроме того, этот код отлично работает в моей локальной установке.

Я не понимаю, почему нулевое исключение string.replace для oldValue выдается во время значения NaviagteURL.

ВОПРОС:

Может ли кто-нибудь помочь мне понять, почему эта функция NavigateURL выдает ошибку string.replace?

заранее спасибо

Редактировать 1:

Я нашел эту запись и Эта проблема JIRA, которая связана. Это связано с тем, что поиск не работает, если не задан основной псевдоним портала. В этом случае он был установлен, и эта проблема, похоже, была исправлена ​​​​в предыдущей версии той, которую я использую, поэтому я не думаю, что это все.

РЕДАКТИРОВАТЬ 2: РЕШЕНИЕ

Когда я создаю объект настроек портала в новой функции поиска DNN 7 GetModifiedSearchDocuments, он не заполняет автоматически свойства PortalAlias и PrimaryAlias элемента >PortalSettings Объект.

Поэтому я создаю PortalAliasController, вручную получаю псевдоним портала и назначаю его объекту PortalSettings.

Такое ощущение, что я делаю что-то изношенное, и создание нового объекта PortalSettingsObject(portalID) должно выполнить эту задачу за меня. Я просмотрел исходный код на gitHub, и кажется, что так и должно быть. Но в моем случае это не так.

Таким образом, следующий код — это то, что я использовал для обработки полного объекта настроек портала, чтобы я мог использовать функцию NavigateURL без ошибок:

        Public Overrides Function GetModifiedSearchDocuments(moduleInfo As ModuleInfo, beginDate As Date) As IList(Of Entities.SearchDocument)
        Try

            Dim SearchDocuments As New List(Of Entities.SearchDocument)

            'get list of changed products
            Dim vc As New ViewsController

            Dim pList As List(Of vw_ProductList_Short_Active) = vc.GetProduct_Short_Active(moduleInfo.PortalID)

            Dim pSettings As New PortalSettings(moduleInfo.PortalID)

            ''use portal alias controller to get primary portal alias of current portal
            Dim pac As New PortalAliasController
            Dim pAlias As PortalAliasInfo = TryCast(pac.GetPortalAliasesByPortalId(moduleInfo.PortalID).Where(Function(a) a.IsPrimary).Single, PortalAliasInfo)
            pSettings.PortalAlias = pAlias
            pSettings.PrimaryAlias = pAlias

            If pList IsNot Nothing Then
                ''for each product, create a searchdocument
                For Each p As vw_ProductList_Short_Active In pList


                    ''format parapeter array for detail url
                    Dim array() As String = {"mid=" + ModID.ToString, "id=" + p.ProductId.ToString, "item=" + p.Name.Replace(" ", "-")}

                    ''format detail url for search item
                    Dim DetailUrl As String = NavigateURL(moduleInfo.TabID, pSettings, "Detail", array)
                    Dim portalAlias As String = pSettings.DefaultPortalAlias
                    DetailUrl = DetailUrl.Replace("///", "//" + portalAlias + "/")
                    ''loop business logic cut out for brevity
                    With SearchDoc
                        .AuthorUserId = p.CreatedByUserId
                        .Body = p.ShortInfo
                        .Description = p.LongInfo
                        .IsActive = True
                        .PortalId = p.PortalId
                        .ModifiedTimeUtc = p.LastUpdatedDate
                        .Title = p.Name + " - " + p.ProductNumber
                        .UniqueKey = Guid.NewGuid().ToString()
                        .Url = DetailUrl
                        .ModuleId = p.ModuleId
                        .ModuleDefId = moduleInfo.ModuleDefID                            
                    End With

                    SearchDocuments.Add(SearchDoc)
                Next

                Return SearchDocuments

            Else
                Return Nothing
            End If

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

    End Function

person J King    schedule 15.12.2014    source источник


Ответы (1)


Единственный String.Replace в DotNetNuke.Entities.Urls.AdvancedFriendlyUrlProvider.GetFriendlyAlias(), из которого может возникнуть ошибка, — это строка № 571:

friendlyPath = friendlyPath.Replace(Globals.AddHTTP(httpAlias), String.Empty);

Строка httpAlias ​​передается из внешней функции: DotNetNuke.Entities.Urls.AdvancedFriendlyUrlProvider.FriendlyUrl(). И это должно было исходить из основной функции, которая возвращает псевдоним портала.

Проверьте, есть ли в таблице PortalSettings запись с SettingName = "DefaultPortalAlias" и правильным значением. Также проверьте, имеет ли ваша таблица PortalAlias ​​правильное значение HttpAlias ​​для вашего портала и имеет ли одна запись для каждого идентификатора портала флаг IsPrimary, установленный в значение true.

person DotNetNuclear    schedule 16.12.2014
comment
спасибо, я не был в состоянии изучить это много. Я думаю, что у меня проблема с тем, как я создаю объект portalSettings. Как только я выясню больше плохого поста здесь. - person J King; 19.12.2014
comment
Хорошо, псевдоним портала по умолчанию правильно установлен в таблице настроек портала, и он установлен в качестве основного псевдонима, а в настройках псевдонима установлено перенаправление. Все еще не могу найти, что происходит - person J King; 22.12.2014
comment
Похоже, проблема в том, что я использую PortalSettings внутри GetModifiedSearchDocuments для нового поиска DNN 7. Объект portalSettings пуст, когда я вызываю GetPortalSettings, и поэтому, когда я вызываю NaviagteUrl и передаю настройки портала, псевдоним пуст, и это вызывает нулевое исключение в стеке вызовов. Я явно не совсем понимаю новую реализацию поиска. - person J King; 22.12.2014
comment
Джей Кинг. Приятно слышать, что вы это исправили. Просто для сравнения посмотрите мой пример бесплатного руководства на моем сайте, где у меня есть реализация ModuleSearchBase. dotnetnuclear.com/articles/tabid/88/ID/16/ - person DotNetNuclear; 23.12.2014
comment
Несмотря на то, что это произошло много времени спустя, я опубликовал решение (редактирование № 2). Я был бы заинтересован в вашем отзыве, так как мне пришлось вручную назначать псевдоним портала и свойства основного псевдонима объекта PortalSettings. Это так и должно работать, или псевдоним портала уже должен быть задан при создании объекта настроек портала. Что касается ошибки замены строки, это произошло из-за отсутствия информации о псевдониме портала. - person J King; 01.03.2015
comment
Джей Кинг, я не могу объяснить, почему псевдоним портала не установлен должным образом в объекте настроек портала. Но если вы посмотрите мою реализацию ModuleSearchBase (ссылка в предыдущем комментарии), вы увидите, что я устанавливаю Url = при создании SearchDocument. Причина в том, что если я установлю атрибуты TabId и PortalId, DNN автоматически создаст URL-адрес при возврате результатов. Вам нужно будет только установить атрибут Url SearchDocument, если вы индексируете контент с внешним URL-адресом. - person DotNetNuclear; 01.03.2015