zoukankan      html  css  js  c++  java
  • silverlight之deeplink学习笔记

    所谓的deeplink技术是为了解决silverlight(或flash)之类的RIA Web应用无法被搜索引擎收录而出现的,属于SEO范畴。

    就拿最常见的企业网站为例,里面有企业简介(About),产品展示(Product),联系我们(AboutUs)...等常见模块,如果全站都用silverlight/flash来做,default.html页面上用object嵌入一个xap/swf就完事了,搜索引擎永远收录到的都是default.html一个页面.

    假如,我们能用 http://www.xxx.com/default.html#/About 能让silverlight切换到企业简介(About)场景,能用".../default.html#/Product” 切换到产品展示模块,能用"../default.html#/Product?id=123" 切换到id=123的产品,这样对于搜索引擎就非常友好了,它会认为这是不同的url,从而能收录更多的页面。

    幸好,silverlight 3中要实现这一点非常容易(SL的设计者们确实想得很周到)

    vs2008中新建(new)一个项目(Project)时,不知道大家有没注意到“Silverlight导航应用程序”这种类型,建一个试试看

    F5编译运行看看,注意浏览器地址栏



    可以发现自动变成了类似 http://localhost:19341/slNavTestPage.aspx#/Home ,页面标题自动变成了"主页",再点击About按钮,地址栏变成了 http://localhost:19341/slNavTestPage.aspx#/About ,页面标题自动变成了"关于",而我们还一行代码都没写,这不正是我们想要的吗?

    如果我们想自己手动达到这种效果,也不困难,新建一个Index.xaml的控件(或页面),内容如下:

    <UserControl x:Class="slNav.Index"
        xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:navigation
    ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" 
        xmlns:uriMapper
    ="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation" 
        
    >

        
    <StackPanel Orientation="Vertical">

            
    <navigation:Frame x:Name="ContentFrame"  Source="/Home" NavigationFailed="ContentFrame_NavigationFailed" Height="300" Navigated="ContentFrame_Navigated">
                
    <navigation:Frame.UriMapper>
                    
    <uriMapper:UriMapper>
                        
    <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>
                        
    <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
                    
    </uriMapper:UriMapper>
                
    </navigation:Frame.UriMapper>
            
    </navigation:Frame>

            
    <TextBlock x:Name="xUri"></TextBlock>

        
    </StackPanel>

    </UserControl>

    关键在于<navigation:Frame>..</navigation:Frame>这个控件,它是一个容器,用于在各页之间跳转导航,同时自动会让地址栏产生刚才的变化.

    有一个Source属性比较关键,可以用来指定导航显示的xaml页,比如你可以指定为"/pages/about.xaml",运行时它将加载/pages/about.xaml到容器中显示,但是可能有些人觉得这种太长了,而且也暴露了网站本身的目录结构,如果能用"/About" 直接显示"/Pages/About.xaml"多好,没问题!

    注意上面的<uriMapper:UriMapper>..<uriMapper:UriMapper>,它提供了地址映射的能力!(很象urlRewriter功能)

    <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>

    表示地址 "/abc" 将自动映射到 "/Views/abc.xaml",地址"/About"将自动映射到"/Views/About.xaml"

    定义了映射规则后,Source属性就可以把"/Views/Home.xaml"简写成"/Home"

    这里有一点要注意,如果您定义多个映射关系,请合理安排顺序

    比如:

    <uriMapper:UriMapper>
             <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>
             <uriMapper:UriMapping Uri="/Link/{id}" MappedUri="/Views/Link.xaml?id={id}"/>
             <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>                      
    </uriMapper:UriMapper>

    这是有效的,输入"..#/Link/3" 将自动映射到 "/Views/Link.xaml?id=3"

    但是如果换一下顺序:

    <uriMapper:UriMapper>
             <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>
             <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>                    

             <uriMapper:UriMapping Uri="/Link/{id}" MappedUri="/Views/Link.xaml?id={id}"/>
    </uriMapper:UriMapper>

    这样是无效的,"..#/Link/3" 永远也得不到正确的映射!因为第二条红色的规则先匹配了,它将会把这个地址能识别的有效部分先翻译成 "/Views/Link.xaml",至于后面的"/3"它不认别,则会原样附加到后面,最终得到的地址是 "/Views/Link.xaml/3",因为/Views/下没有Link.xaml这个目录,所以当然会找不到路径而出错!

    大概原则:特殊的规则写在前面,通用的规则写在后面


    另一个问题,导航到类似"/Product?id=123"这种地址后,在silverlight中如何象Asp.net中的Request.QueryString那样接受参数呢?

    可以在product.xaml.cs中类似如下处理:

     1
     2// 当用户导航到此页面时执行。
     3        protected override void OnNavigatedTo(NavigationEventArgs e)
     4        {
     5            IDictionary<stringstring> _dicParm = this.NavigationContext.QueryString;
     6
     7            if (_dicParm.ContainsKey("id")) 
     8            {
     9                xParm.Text = "产品id = " + _dicParm["id"];
    10            }
                
    11        }

     
    要注意的是:参数名是区分大小写的,也就是说 /product/?id=123 跟 /product/ID=123是不一样的!(这点跟asp.net不同)

    最后看一下标题的问题,观察一下Silverlight中Page页自动生成的xaml代码:

    1<navigation:Page x:Class="slNav.Views.Link" 
    2           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    3           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    4           xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6           mc:Ignorable="d"
    7           xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
    8           d:DesignWidth="640" d:DesignHeight="480"
    9           Title="友情链接">

    没错,就是Title属性!

    那么运行时,silverlight是如何自动把xaml中的title设置到html/aspx网页标题的呢?

    其实内部原理我也不知道,哈! 不过我经过多次测试发现,vs.net自动生成的测试页html代码中

    <div id="silverlightControlHost">
            
    <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
              
    <param name="source" value="ClientBin/slNav.xap"/>
              
    <param name="onError" value="onSilverlightError" />
              
    <param name="background" value="white" />
              
    <param name="minRuntimeVersion" value="3.0.40624.0" />
              
    <param name="autoUpgrade" value="true" />
              
    <href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none">
                   
    <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
              
    </a>
            
    </object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;0px;border:0px"></iframe></div>

    总是有一行<iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;0px;border:0px"></iframe>,如果你把这个去掉,虽然页面照样能显示,但是silverlight就没办法自动设置网页标题了,而且连这个iframe的id都不能变,估计是silverlight内部定死了。

    更多细节,欢迎大家补充。

    转载请注明出自菩提树下的杨过

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    VS2005中的WebApplication和WebSite
    CodeFile 与 CodeBehind 的区别
    vs2005默认浏览器(IE)灵异事件
    杭电OJ第4252题 A Famous City
    湘大OJ第1490题 Generating Random Numbers
    中南OJ 2012年8月月赛 B题 Barricade
    中南OJ 2012年8月月赛 H题 Happy watering
    杭电OJ第4245题 A Famous Music Composer
    中南OJ 2012年8月月赛 I题 Imagination
    杭电OJ第4256题 The Famous Clock
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1597493.html
Copyright © 2011-2022 走看看