今天实验dnn建立子portal的时候,发现建立了子portal后,却没法访问。经过分析源代码后确认是dnn的bug。
在选择建立子portal的时候,如下:
默认情况下dnn会在Portal Alias中把端口也加上去。
当按这种默认方式建立好子portal后,访问localhost:10018/DotNetNuke_Maintenance/Portal2的话会提示找不到服务器。
需要去掉端口,这时候才能访问,但是这时候访问的时候发现访问到的是默认的portal,即Portal0,而不是我刚才建立的Portal2。
这时候的浏览器URL变为:
发现这时候的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
解析为:
时发生了错误。
错误的原因在于多加了端口。
当我们在建立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>