注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

高级菜鸟

积累并顺便分享AI,启动技术,C#,ASP.net等知识的地方

 
 
 

日志

 
 

DNN的Friendly URL剖析及应用  

2011-03-30 02:55:05|  分类: Dotnetnuke |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

传统的URL的形式如同:

http://www.dotnetnuke.com/default.aspx?tabid=510&Name=Pm2004

页面通过parameter=value的形式给页面传递参数,页面根据参数加载不同的内容。但是,DNN因为以下原因放弃了传统的形式:

(1)       这种方式不利于阅读和人们的理解。不够人性化。

(2)       很多搜索引擎会忽略,搜索引擎会避免参数。不利于网络搜索。

目标:

(1)       有利于搜索引擎发现

(2)       有利于人们阅读

(3)       适合child portal

(4)       不影响其它应用

(5)       性能

DNN Friendly URL基本思想

DNN的解决方案类似于翻译员,将一种语言翻译成另外的一种语言。最终的本质还是带有参数的形式,只是在表现上,在URL的字符串中出现的是Friendly的。这里用到的一个术语是URL Schema的规则集。通过这组规则完成原生URLFriendly URL之间的相互翻译。

如:

原始的URL:

http://www.dotnetnuke.com/default.aspx?tabid=703

被翻译为:

http://www.dotnetnuke.com/tabid/703/default.aspx

 

URL Schema将一种表达方式转化为另一种表达方式,这种结果是确定的,而且是唯一的。这是我们谈到的一种情况,就是请求URL的转换方式。HTTP还包含一种响应模式,我们的机制同时要满足这样的要求,例如用户可能希望看到新闻组的网页在浏览器中显示的是:

http://www.dotnetnuke.com/About/News.aspx

而不是:

http://www.dotnetnuke.com/About/News/tabid/703/Default.aspx

 

相关组件

URL Schema

SiteUrls.config文件中定义了相应的规则:

 

<?xml version="1.0" encoding="utf-8" ?>

<RewriterConfig>

     
<Rules>

         
<RewriterRule>

              
<LookFor>.*/TabId/(\d+)(.*)/Logoff.aspx</LookFor>

              
<SendTo>~/Admin/Security/Logoff.aspx?tabid=$1</SendTo>

         
</RewriterRule>

         
<RewriterRule>

              
<LookFor>.*/TabId/(\d+)(.*)/rss.aspx</LookFor>

              
<SendTo>~/rss.aspx?TabId=$1</SendTo>

         
</RewriterRule>

         
<RewriterRule>

              
<LookFor>[^?]*/TabId/(\d+)(.*)</LookFor>

              
<SendTo>~/Default.aspx?TabId=$1</SendTo>

         
</RewriterRule>

     
</Rules>

</RewriterConfig>


结合对源码的分析,这里的规则是全匹配,而不是局部的匹配。同时利用正则表达式

Match Groups属性,将匹配的Value取出,并填入SendTo中,如$1。

 

HTTP Module

Web.Config中定义了:

 <httpModules>

      
<add name="UrlRewrite" type="DotNetNuke.HttpModules.UrlRewriteModule, 

                                 DotNetNuke.HttpModules.UrlRewrite"
 />

    
</httpModules>

   
HTTP请求中,IIS允许开发者在HTTP请求的管道中插入若干Module来处理加工/处理该请求。Module像在管道中的一个截面,流经这个截面的信息都被Module处理一下。

 
在URLRewriteModule Init 只是定义了一个事件而已

AddHandler application.BeginRequest, AddressOf Me.OnBeginRequest

OnBeginRequest中处理的过程比较复杂,这个方法中包含了一些基本的URL转换规则定义,另外的一部分在SiteUrls.Config中以URL Schema的形式进行了定义。

基本的步骤是:

  •        检查请求URL的合法性,并将其转换为绝对请求地址。
  •        读入SiteUrls.Config文件中的规则。
  •        轮询这些规则,如果匹配则进行转换。
  •       在转换TabID,Portal Alias等基本规则。
  •        其他的一些处理。

Friendly Url的实战

需求

在网站的开发中,我们经常需要跳转,从一个页面转入另外的页面,虽然我们理解了DNN Friendly Url的基本思想,但是在实战中,我们拼凑一个这样的URL还是很费力的,为此DNN提供了几个辅助类和相应的方法。下面我们介绍这些方法和类,并且给出一些应用。

DNNFriendlyUrlProvider

沿袭ASP.NET2/DNN的一贯思想,使用Provider的机制来灵活定制程序的运行方式,Friendly Url也是采用这种方式,在Web.Config中定义了:

<friendlyUrl defaultProvider="DNNFriendlyUrl">

      
<providers>

        
<clear />

        
<add name="DNNFriendlyUrl" type="DotNetNuke.Services.Url.FriendlyUrl.DNNFriendlyUrlProvider, DotNetNuke.HttpModules.UrlRewrite" includePageName="true" regexMatch="[^a-zA-Z0-9 _-]" />

      
</providers>

    
</friendlyUrl>



它实现了

 

public override string FriendlyUrl(TabInfo tab, string path, string pageName, string portalAlias)

public override string FriendlyUrl(TabInfo tab, string path, string pageName, PortalSettings settings)

public override string FriendlyUrl(TabInfo tab, string path, string pageName)

public override string FriendlyUrl(TabInfo tab, string path)


等方法。

我们考查一下下面这个函数

 

 

public override string FriendlyUrl(TabInfo tab, 

string path, 

string pageName, 

PortalSettings settings)


其中

Tab其实就是DNN portal每个菜单(或者页面);

       Path就是路径,可能是~开头的相对路径,也可能是绝对路径,可能是/也可能是\。如果有参数(&?形式的参数)就包含在这个字符串中。

       PageName是页面文件,比如default.aspx,这个页面会替换掉Path中的页面。

       Setting主要是为了取出Portal的根路径或者Alias路径

通过这些参数能够组合,格式化成一个Friendly Url。注意最后形成的Friendly URL中可能也含有参数,目前regexMatch="[^a-zA-Z0-9 _-]这些参数才可以被Friendly化。

EditURLNavigateURL

翻阅DNN的代码,经常会碰到使用EditURL函数,比如,最常见的我们在可以编辑的Item前面有一支笔,点击后就跳到编辑的页面:

<asp:HyperLink NavigateUrl='<%# EditURL("ItemID",DataBinder.Eval(Container.DataItem,"ItemID")) %>' Visible="<%# IsEditable %>" runat="server" ID="Hyperlink1"><asp:Image ID=Hyperlink1Image Runat=server ImageUrl="~/images/edit.gif" AlternateText="Edit" Visible="<%#IsEditable%>" resourcekey="Edit"/></asp:hyperlink>

EditURL主要是为了跳转到Edit页面而定义的,当然它也可以跳转到其他Control页面。它在模块的基类PortalModuleBase中被定义。它被重载了5次,可以什么参数都不带,也可以Public Function EditUrl(ByVal KeyName As StringByVal KeyValue As StringByVal ControlKey As StringByVal ParamArray AdditionalParameters As String()) As String

它处在模块的基类中,很方便使用,也是出镜率很高的函数之一。

 

它调用Global.vbNavigateURL函数,这是一个Static函数。NavigateURL调用Global.vb中的FriendlyUrl函数,该函数按照Provider的机制加载相应的DNNFriendlyUrlProvider

DotNetNuke.Services.Url.FriendlyUrl.FriendlyUrlProvider.Instance().FriendlyUrl(tab, path, pageName, portalAlias)

 

应用

DNN 的开发过程中,经常需要跳转页面,下面就不同的场合下给出解决的对策(以下描述的主要是目标URL串如何生成):

(1)       在模块定义中定义了两个或多个Control,需要从一个Control页面跳到另一个页面。

同一个模块,不同Control之间的跳动,而且不涉及参数的传递,使用EditUrl(ControlKey)

(2)       上述的情况,在很多情况下我们需要传入一些参数,特别是ItemID,在接收的模块中会提取此参数进行判断。比如在Blog模块中:

 

定义了View_Entry Control,可能需要从View Blog中跳转,就可以用EditUrl(“ItemID”,”123”, View_Entry)方法。

同一个模块,不同Control之间的跳动,而且涉及某一个参数的传递,可以使用

EditUrl(KeyName, KeyValue, ControlKey),如果是Edit Control可以省略为

EditUrl(KeyName, KeyValue)

(3)       在有的时候我们可能需要传递更多的参数,我们使用EditUrl(KeyName, ByVal KeyValue, ControlKey, ByVal ParamArray AdditionalParameters As String())

最后的参数是可以被罗列的,比如

       EditUrl(“CaterogyCode”,”123”,”ViewDetail”,”StoreID”,”431”)

它的含义是,跳转到ViewDetail Control页面里,其中CaterogyCode=123StoreID=431等等。

(4)       如果我们希望在不同的Tab中进行跳转,比如我跳转到首页,或者已知的某个TabID的页面可以NavigateURL(ByVal TabID As Integer)

以下代码帮助跳转到"产品"页:

 

TabController ctlTab = new TabController();

TabInfo objTab 
= ctlTab.GetTabByName("产品");

this.Response.Redirect(Globals.NavigateURL(objTab.TabID), true);


(5)      

最为灵活的

Public Function NavigateURL(ByVal TabID As IntegerByVal IsSuperTab As BooleanByVal settings As PortalSettings, ByVal ControlKey As StringByVal ParamArray AdditionalParameters As String()) As String

函数,借助它能够带上ControlKey以及N多的额外参数。

 

总结上面两个函数:

在同一个模块不同Control之间跳转,可以使用EditUrl

在不同Tab之间跳转使用NavigateUrl

他们都可以传递若干参数。

 

这两个函数都是没有办法改变最终的aspx文件名的,但是Globals.vb中定义的FriendlyUrl可以实现Path的自定义,更换*.aspx等等。具有更大的灵活性,但是使用不多见。

http://www.cnblogs.com/reommmm/articles/1170794.html



在DNN中如何使FriendlyURL使用PageName作为页面名称

在DNN中,有三类URL,分别是:"default", "Friendly"和"Human Friendly"。

示例如下:

default: dotnetnuke.com/default.aspx?tabid=57

friendly: dotnetnuke.com/tabid/57/Default.aspx

human friendly dotnetnuke.com/AwesomePage.aspx

 

对与friendly url,大家一定很熟悉了,到这里可以打开friendly url:

Host->Host Settings

Friendly Url Settins这一节,勾选


image

 


在Host > Host Settings > Advanced Settings > Friendly Url Settings里可以开启Friendly Urls

开启Friendly Url后连接连接看起来是这样的

http://dnn.dnnmix.com/home/Tabid/36/default.aspx

我们可不可以让连接变得更人性化一些,去掉default.aspx和tabid呢,答案是可以的。

如何开启Human Friendly Url

在web.config里加入urlFormat=”HumanFriendly” 开启人性化连接

1         <friendlyUrl defaultProvider="DNNFriendlyUrl">
2             <providers>
3                 <clear/>
4                 <add name="DNNFriendlyUrl" 
                 type
="DotNetNuke.Services.Url.FriendlyUrl.DNNFriendlyUrlProvider, DotNetNuke.HttpModules" 
                 includePageName
="true" 
                 regexMatch
="[^a-zA-Z0-9 _-]" 
                     urlformat
="HumanFriendly"/>
5             </providers>
6         </friendlyUrl>


开启人性化连接后的连接

http://dnn.dnnmix.com/home.aspx

看起来是不是简洁多了

我在DNN4.7 以后的版本和 DNN 5.0 中测试了一下这个方法都是有效的

如果你的网站使用端口

在使用端口的网站中你会发现人性化连接是无效的,这时候你要添加一个网站别名(portal alias)

例如你的网地址是 http://dnn.dnnmix.com:8080 你的网站别名应该是dnn.dnnmix.com:8080, 要使用人性化连接你还要添加一个dnn.dnnmix.com的网站别名才可以在有端口号的网站中使用人性化连接.

这应该算是个Bug吧不过在DNN5.0 还没有修复.

高级菜鸟推荐阅读:
  评论这张
 
阅读(1561)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018