DNN建立子Portal的bug

来源:互联网 发布:淘宝鸿星尔克女运动鞋 编辑:程序博客网 时间:2024/05/22 01:52

今天实验dnn建立子portal的时候,发现建立了子portal后,却没法访问。经过分析源代码后确认是dnn的bug。

在选择建立子portal的时候,如下:

默认情况下dnn会在Portal Alias中把端口也加上去。

当按这种默认方式建立好子portal后,访问localhost:10018/DotNetNuke_Maintenance/Portal2的话会提示找不到服务器。

需要去掉端口,这时候才能访问,但是这时候访问的时候发现访问到的是默认的portal,即Portal0,而不是我刚才建立的Portal2。

这时候的浏览器URL变为:

http://localhost:10018/DotNetNuke_Maintenance/Default.aspx?alias=localhost:10018/DotNetNuke_Maintenance/portal2

发现这时候的alias参数又带有端口参数。

问题分析:

1、在建立子portal的时候,如果加上端口参数,出现找不到服务器或者网页的问题。

在UrlRewriteModule第380行:

 ' parse the Request URL into a Domain Name token
                DomainName = GetDomainName(Request, True)

这里得到的DomainName是不带参数的。

所以稍后,在424行:

 'using the DomainName above will find that alias that is the domainname portion of the Url
                'ie. dotnetnuke.com will be found even if zzz.dotnetnuke.com was entered on the Url
                objPortalAliasInfo = PortalSettings.GetPortalAliasInfo(PortalAlias)
                If Not objPortalAliasInfo Is Nothing Then
                    PortalId = objPortalAliasInfo.PortalID
                End If

中,objPortalAliasInfo将返回空,即根据这个DomainName在数据库中无法找到对应的PortalAlias设置。

所以会出现问题。

 

2、当不添加端口的时候,会显示默认portal。

这时候,我们发现Url中的alias参数是有端口的,说明在将

http://localhost:10018/DotNetNuke_Maintenance/Portal2

解析为:

http://localhost:10018/DotNetNuke_Maintenance/Default.aspx?alias=localhost:10018/DotNetNuke_Maintenance/portal2

时发生了错误。

错误的原因在于多加了端口。

当我们在建立Portal2时,dnn在网站根目录下添加了一个目录Portal2,里面有个Default.aspx文件,这个文件起的就是个重定向的作用,用来将我们这种地址的访问(http://localhost:10018/DotNetNuke_Maintenance/Portal2)转化为对网站目录Default.aspx的访问。并且将alias参数设置好,以便Default.aspx加载相应的Portal的Tab。

分析Portal2/Default.aspx就很容易发现问题:

<%@ Page language="VB" %>
<%@ Import Namespace="DotNetNuke" %>

<script runat="server">

    Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)

            Dim DomainName As String
            Dim ServerPath As String
            Dim URL() As String
            Dim intURL As Integer

            ' parse the Request URL into a Domain Name token
            URL = Split(Request.Url.ToString(), "/")
            For intURL = 2 To URL.GetUpperBound(0)
                Select Case URL(intURL).ToLower
                    Case "admin", "desktopmodules", "mobilemodules", "premiummodules"
                        Exit For
                    Case Else
                        ' check if filename
                        If InStr(1, URL(intURL), ".aspx") = 0 Then
                            DomainName = DomainName & IIf(DomainName <> "", "/", "") & URL(intURL)
                        Else
       Exit For
                        End If
                End Select
            Next intURL

            ' format the Request.ApplicationPath
            ServerPath = Request.ApplicationPath
        If Mid(ServerPath, Len(ServerPath), 1) <> "/" Then
            ServerPath = ServerPath & "/"
        End If
        
        
        DomainName = ServerPath & "Default.aspx?alias=" & DomainName
       
        Response.Redirect(DomainName, True)
 
    End Sub

</script>

这里,并没有同样地调用DotNetNuke.Common.Globals.GetDomainName方法,而是自己进行DomainName 的解析,这里的解析并没有解析端口。所以Response.Redirect(DomainName, True)中的的DomainName中的alias参数就是含有端口的。

因此当用带有端口的alias参数传递过去的时候,在UrlRewriteModule处理的时候,使用这个alias查询portal的时候,又失败了。

 ' alias parameter can be used to switch portals
                If Not (Request.QueryString("alias") Is Nothing) Then
                    ' check if the alias is valid
                    If Not PortalSettings.GetPortalAliasInfo(Request.QueryString("alias")) Is Nothing Then
                        ' check if the domain name contains the alias
                        If InStr(1, Request.QueryString("alias"), DomainName, CompareMethod.Text) = 0 Then
                            ' redirect to the url defined in the alias
                            Response.Redirect(GetPortalDomainName(Request.QueryString("alias"), Request), True)
                        Else ' the alias is the same as the current domain
                            PortalAlias = Request.QueryString("alias")
                        End If
                    End If
                End If

 ' parse the Request URL into a Domain Name token
                DomainName = GetDomainName(Request, True)

所以,就又显示了默认网站。

问题的原因在于Portal2/Default.aspx和UrlRewriteModule.vb对DomainName的处理不一致造成的。这种处理在于没有端口的情况下,例如默认80端口时不会有问题,但是如果有端口的时候就会有问题。

所以需要把2边的处理变成相同的,既然已经写了对DomianName处理的共用方法:DotNetNuke.Common.Globals.GetDomainName,在Portal2/Default.aspx中就没有必要再写那么多代码去分析了。直接调用就行了。

改为如下代码即可:

 <%@ Page language="VB" %>
<%@ Import Namespace="DotNetNuke" %>

<script runat="server">

    Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)

            Dim DomainName As String
            Dim ServerPath As String


                   ' format the Request.ApplicationPath
            ServerPath = Request.ApplicationPath
        If Mid(ServerPath, Len(ServerPath), 1) <> "/" Then
            ServerPath = ServerPath & "/"
        End If
       
        DomainName = DotNetNuke.Common.Globals.GetDomainName(Request, True)
        DomainName = ServerPath & "Default.aspx?alias=" & DomainName
       
        Response.Redirect(DomainName, True)
 
    End Sub

</script>

原创粉丝点击