在ASP.NET 2.0中建立站点导航层次(2)
上一篇 / 下一篇 2007-03-16 10:23:00 / 个人分类:心得笔记
站点导航特性可以根据授权规则过虑提供程序所返回的SiteMapNode实例。XmlSiteMapProvider可以根据当前网站使用的文件和URL授权规则过虑节点。
下面的例子使用了窗体授权规则,预定义的用户凭证存储在web.config中。在global.asax中,根据用户名,用户的角色都被附加到当前的请求上。在web.config中,嵌套在
请使用下面三个帐户之一运行示例:
· Userid: SectionOne Password: SectionOne
· Userid: SectionTwo Password: SectionTwo
· Userid: AllSections Password: AllSections
在页面的右上角有一个"退出"链接,因此你可以用不同的帐号登陆和退出。请注意,根据你登陆所使用的帐号不同,导航UI显示的Treeview和Menu控件会自动地反映该用户所获得的访问权限。提供程序自动地过虑了返回的节点--实现这种功能不需要额外的代码。用"SectionOne"帐号登陆的时候,只在左边的Treeview控件中显示"SectionOne"链接和外部链接。用"SectionTwo"帐号登陆的时候,只在左边的Treeview控件中显示"SectionTwo"链接和外部链接。用"AllSections"帐号登陆的时候,Treeview控件中显示了所有的链接。web.config中的授权规则配置为给"SectionOne"和"SectionTwo"层次授予了部分访问权力。
这个示例还演示了如何处理应用程序目录范围之外的URL安全性。在web.sitemap文件中,外部链接的节点使用了roles属性。语法roles="*"授予所有用户访问和查看导航控件中的节点的权力。语法roles="Adminstrators,Regular Users"只允许这些角色的用户检索和查看导航控件中的节点。由于在示例中global.asax文件把用户分成了这两种角色,所以你一直可以看到外部链接。
开发者可以选择同时使用文件/URL授权规则和roles属性来控制用户对SiteMapNode实例的访问权。如果两者的设置信息都是正确的,站点导航提供程序就会根据文件/URL授权规则和roles属性中的角色来对当前用户进行认证。如果当前用户通过了任何一种授权检查,就可以访问节点。
如果默认的安全性操作不适用于你的应用程序,开发者还可以从XmlSiteMapProvider衍生类,并用自定义的节点授权实现来重载IsAccessibleToUser方法。
Web.config的内容
| 以下是引用片段: <system.web> <authentication mode="Forms"> <forms name=".ASPXAUTH" loginUrl="Login.aspx" protection="All" timeout="30" path="/" requireSSL="false" slidingExpiration="true" defaultUrl="Home.aspx" cookieless="UseCookies" enableCrossAppRedirects="false"> <credentials passwordFormat="Clear"> <user name="SectionOne" password="SectionOne"/> <user name="SectionTwo" password="SectionTwo"/> <user name="AllSections" password="AllSections"/> </credentials> </forms> </authentication> <authorization> <deny users="?"/> </authorization> </system.web> <location path="SectionOne.aspx"> <system.web> <authorization> <allow users="SectionOne" roles="Administrators" /> <deny users="*"/> </authorization> </system.web> </location> <location path="SectionOne"> <system.web> <authorization> <allow users="SectionOne" roles="Administrators"/> <deny users="*"/> </authorization> </system.web> </location> <location path="SectionTwo.aspx"> <system.web> <authorization> <allow users="SectionTwo" roles="Administrators"/> <deny users="*"/> </authorization> </system.web> </location> <location path="SectionTwo"> <system.web> <authorization> <allow users="SectionTwo" roles="Administrators"/> <deny users="*"/> </authorization> </system.web> |
本地化站点地图数据
存储在sitemap文件中的导航数据可能需要进行本地化(localize)。
下面的示例包含了英语和法语的本地化文本。它的web.sitemap文件使用两种类型(隐式的和显式的)的本地化表达式来实现这种功能。Sitemap文件在根siteMap元素中使用了enableLocalization=true就表明它使用了本地化数据。
站点地图文件的隐式表达式让开发者能够轻易地用查找键(lookup key)标记每个
当XmlSiteMapProvider根据web.sitemap文件中的信息检索SiteMapNode的时候,它根据SiteMapNode属性的名称、resourceKey和为提供程序配置的siteMapFile属性的值来检索字符串资源。使用示例中的"Autos"节点的时候,提供程序(provider)会根据当前的文化来查找以"web.sitemap"开头的资源文件。
这意味着,对于一个发送法语头信息的浏览器来说,提供程序会查找名称为web.sitemap.fr.resx的资源文件。在这个资源文件中,提供程序会依据resourceKey + "." + [SiteMapNode属性名]来查找资源键。例如,把"Autos"节点的Title属性当作例子,提供程序会在web.sitemap.fr.resx资源文件中查找键为Autos.Title的资源。
显式表达式使开发者对包含本地资源的文件和资源键(resource key)的名称有更强的控制能力。在示例web.sitemap中,第一个
你可以运行示例来查看站点地图本地化的效果。把英语作为默认语言的浏览器会显式英语文本。如果使用IE,你可以通过点击"工具->Internet选项",并在"通用"选项卡点击"语言"按钮,点击"添加"按钮并选择添加"法语"。如果需要,还需要选中法语并点击"向上移动"按钮,使它成为IE的默认请求语言。把默认的语言改成法语之后,刷新示例页面。请注意,Menu、Treeview和SiteMapPath控件中的文本自动地显式为App_GlobalResources目录中存放的法语资源文件中的法语文本。
Web.sitemap的内容
| 以下是引用片段: <?xml version="1.0" encoding="utf-8" ?> <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" enableLocalization="true"> <siteMapNode url="~/Default.aspx" title=" $resources: Title, MyTitle , Home" description="Default page description when no localized value exists." > <siteMapNode url="~/Category.aspx" resourceKey="Category"> <siteMapNode title="Autos" description="Autos" url="~/Autos.aspx" resourceKey="Autos" /> <siteMapNode title="Games" description="Games" url="~/Games.aspx" resourceKey="Games" /> <siteMapNode title="Health" description="Health" url="~/Health.aspx" resourceKey="Health" /> <siteMapNode title="News" description="News" url="~/News.aspx" resourceKey="News" /> </siteMapNode> </siteMapNode> </siteMap> |
修改提供程序(Provider)返回的站点导航数据
存储在web.sitemap中、供XmlSiteMapProvider使用的导航数据是静态的--这些数据被载入内存中并作为只读数据存储。但是,很多站点的导航结构是根据查询字符串的值来参数化的。例如,新闻组(newsgroup)站点可能拥有良好定义的页面结构(例如,主页、新闻类别页面和新闻内容页面),但是实际的内容可能会有很大的不同,这依赖于查询字符串中的标识符。尽管把每种可能的查询字符串值都存储在
站点导航特性在SiteMapProvider基类中暴露了SiteMapResolve事件。可以使用SiteMap.SiteMapResolve或直接使用提供程序SiteMap.Provider.SiteMapResolve来执行这个事件。这个事件的返回值是一个SiteMapNode实例。你可以在自己的事件处理程序中编写自定义逻辑来建立SiteMapNode实例的层次结构。这个逻辑可以修改每个SiteMapNode的属性,因此URL和Title等属性会反映查询字符串带有的数据信息。
下面的例子在global.asax中注册了一个事件处理程序。这个事件处理程序的代码是App_Code目录中的一个类。这个自定义的类复制与当前页面对应的SiteMapNode实例。XmlSiteMapProvider返回的节点都是只读的,而调用SiteMapNode上的Clone方法返回的是可写入的节点。在实例中,如果给Clone传递了true值,将导致当前的SiteMapNode和它的所有父节点都是可写入的。这个类的代码的其它部分检查当前的页面和当前页面的查询字符串,确定当前页面位于站点层次结构的什么位置。代码修改了URL和Title属性,包含一些额外的信息,这样SiteMapPath控件显示的导航UI就反映了网站用户为到达当前页面的实际点击路径。
运行示例的时候,你开始位于站点的主页。SiteMapPath控件也反映了这一点。点击任何链接都会带你进入分类页面,它显示相关新闻类别中的新闻链接。请注意,如果你把鼠标停留在SiteMapPath控件的最后一个链接上,浏览器状态栏中显示的URL包含了查询字符串信息(它指定了新闻类别)。点击任何一个发布链接都会把你带回到新闻发布页面。如果你把鼠标停留SiteMapPath控件的链接上,可以注意到控件中的最后两个链接带有的URL和Title包含了点击路径的正确查询字符串和描述信息。如果你导航到站点的主页,并点击其它的新闻组和内容链接,SiteMapPath控件会被更新并反映第二次点击的链接。
| 以下是引用片段: Public Class PathExpansionHandler Public Shared Function ExpandPath(ByVal sender As Object, ByVal e As SiteMapResolveEventArgs) As SiteMapNode '获取当前和之前节点的引用 Dim nodeCopy As SiteMapNode = SiteMap.CurrentNode.Clone(True) Dim tempNode As SiteMapNode = nodeCopy 'Check if there is a newsgroup type in the query string Dim typeID As String = Nothing Dim typeIDUrlEncoded As String = Nothing If Not String.IsNullOrEmpty(e.Context.Request.QueryString("type")) Then typeID = e.Context.Server.HtmlEncode(e.Context.Request.QueryString("type")) typeIDUrlEncoded = e.Context.Server.UrlEncode(e.Context.Request.QueryString("type")) End If '首先执行发布页面URL的固定 '如果查询字符串中包含发布ID,我们就知道当前节点式发布页面 If Not String.IsNullOrEmpty(e.Context.Request.QueryString("postingID")) Then Dim postingID as string = _ e.Context.Server.HtmlEncode(e.Context.Request.QueryString("postingID")) Dim postingIDUrlEncoded as string = _ e.Context.Server.UrlEncode(e.Context.Request.QueryString("postingID")) Dim NewUrl As String = tempNode.Url + "?type=" + typeIDUrlEncoded + "&postingID=" + postingIDUrlEncoded Dim NewTitle As String = tempNode.Title + ": " + postingID tempNode.Url = NewUrl tempNode.Title = NewTitle tempNode = tempNode.ParentNode End If '然后,对新闻组页面进行固定 '这时候nodeCopy 变量知贤了新闻组节点 If Not String.IsNullOrEmpty(e.Context.Request.QueryString("type")) Then Dim NewUrl As String = tempNode.Url + "?type=" + typeIDUrlEncoded Dim NewTitle As String = tempNode.Title + ": " + typeID tempNode.Url = NewUrl tempNode.Title = NewTitle End If '最后返回当前节点 Return nodeCopy End Function End Class |
URL映射
URL映射特性利用web.config中存储的配置信息把收到的请求重映射(remap)到不同的URL。重映射发生在对请求的所有其它处理操作之前。下面的例子演示的是重映射一个页面请求,实际上任意文件类型都可以把请求重映射到不同的URL。
定义重映射URL
URL映射的配置信息存储在web.config中。
示例web.config为大量的url定义了映射规则。示例使用的web.sitemap文件定义的大量带有URL值的节点都会被重映射。其结果是,URL映射和站点导航的组合使用,使得开发者可以用友好的url来定义导航结构,并使用URL映射把请求重新写到不同的页面来执行实际的处理过程。
当你运行示例的时候,请注意Menu和Treeview控件是如何根据web.sitemap文件中定义的站点结构来显示导航数据的。如果你把鼠标停留在Treeview控件或右上角的SiteMapPath控件的链接上方,状态栏中显示的url是一个友好的url链接。当你点击任何导航链接的时候,实际运行的页面是Default.aspx。但是,Menu、Treeview和SiteMapPath控件中的导航信息仍然反映为友好的URL结构。
在页面的底部你还可以看到Request.Path、Request.QueryString["category"]和Request.RawUrl返回的值。Request.Path和Request.QueryString["category"]返回的值一直反映重映射进入站点的url的结果。但是,Request.RawUrl的值反映了重映射之前的友好的url。当站点导航特性试图把url信息与sitemap文件包含的数据进行匹配的时候,它会使用Request.RawUrl。如果匹配的值没有找到,XmlSiteMapProvider就把Request.Path作为替代者。在例子中,所有的友好url在web.sitemap文件中都有条目,因此使用站点导航的控件一直根据友好的url来显示和引用节点。
| 以下是引用片段: <?xml version="1.0" ?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <system.web> <urlMappings enabled="true"> <add url="~/Category.aspx" mappedUrl="~/Default.aspx?category=default" /> <add url="~/Autos.aspx" mappedUrl="~/Default.aspx?category=autos" /> <add url="~/Games.aspx" mappedUrl="~/Default.aspx?category=games" /> <add url="~/Health.aspx" mappedUrl="~/Default.aspx?category=health" /> <add url="~/News.aspx" mappedUrl="~/Default.aspx?category=news" /> </urlMappings> </system.web> </configuration> |
标题搜索
日历
|
|||||||||
| 日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
| 1 | 2 | 3 | 4 | 5 | 6 | ||||
| 7 | 8 | 9 | 10 | 11 | 12 | 13 | |||
| 14 | 15 | 16 | 17 | 18 | 19 | 20 | |||
| 21 | 22 | 23 | 24 | 25 | 26 | 27 | |||
| 28 | 29 | 30 | |||||||
我的存档
数据统计
- 访问量: 4799
- 日志数: 137
- 建立时间: 2006-11-01
- 更新时间: 2008-04-29
