一、按模块分包
一般大型的Silverlight应用,都会按模块分解成多个silverlight project,编译后就有多个xap包,然后在需要用到的场景按需加载。我近期开发的这个项目不需要全站Silverlight,而是aspx混合silverlight,说得更白点,就是把相应的子模块xap包嵌入aspx.
这样分包就简单多了:直接用js控制dom元素,修改object元素中的source,动态设置成不同的xap即可实现无刷新的加载不同模块。(这比网上主流的方式:用WebClient动态下载xap包,最终再反射加载,个人觉得更简单。当然,这种方式不适用于整站Silverlight的项目)
二、按需反射加载xap中的页面
上面讨论的办法,只是解决了按需加载不同的xap文件,但是如果一个xap中有多个页面,如何确定加载某个xap后,显示其中的哪个页面呢?
答案:参数传入+反射
silvelright以object标签嵌入html时,可以指定一些传入参数,类似下面这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 | < object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> < param name="source" value="ClientBin/Basic.xap" /> < param name="onError" value="onSilverlightError" /> < param name="background" value="white" /> < param name="minRuntimeVersion" value="4.0.50826.0" /> < param name="autoUpgrade" value="true" /> < param name="initParams" value="page=Basic.City" /> < a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" style="text-decoration: none"> < img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style: none" /> </ a > </ object > |
注意其中的<param name="initParams" value="page=Basic.City"/>这表明我们想让City页面在加载成功后显示。
那么,SL中如何接受这个参数呢?看下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | private void Application_Startup( object sender, StartupEventArgs e) { //检测有无传入参数 if (e.InitParams != null && e.InitParams.ContainsKey( "page" )) { string _pageName = e.InitParams[ "page" ]; //根据page参数,动态反射加载相应的实例 Assembly asm = this .GetType().Assembly; UserControl _page = asm.CreateInstance(_pageName) as UserControl; this .RootVisual = _page; } else { //如果没有参数传入,则显示默认页面 this .RootVisual = new Airport(); } } |
三、SEO优化
这是RIA应用经常会遇到的一个问题,前面提到的处理方法并未涉及这一块,默认情况下:xap模块的动态加载,以及根据参数动态反射加载不同页面,都不会改变浏览器的地址,所以搜索引擎会始终认为这是一个页面,最终也只能收录一个网址。
为了对搜索引擎更友好,可以在地址栏的#部分做些手脚,最终要到达的效果:
如果动态加载Basic.xap模块,且显示该模块中的City页面时,我们可以让地址栏类似: http://localhost:1223/Default.aspx#Basic|Basic.City
切换到User.xap模块(即用户管理模块),且显示该模块中的User页面时,我们可以让地址栏类似:http://localhost:1223/Default.aspx#User|User.User
这样,虽然都是同一个default.aspx页面,但是搜索引擎却认为这是二个不同的url,会搜录二个地址。
default.aspx完整代码如下:
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | <%@ Page Language="c#" AutoEventWireup="true" %> <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> < html xmlns="http://www.w3.org/1999/xhtml"> < head runat="server"> < title >Silverlight SEO优化及分包下载</ title > < style type="text/css"> html, body { height: 100%; overflow: auto; font-size:12px; } body { padding: 0; margin: 0; } #silverlightControlHost { height: 100%; text-align: center; } #nav { line-height:30px; text-align: center; background: #efefef; padding: 5px; } #nav a { padding: 0px 10px; } </ style > < script type="text/javascript" src="Silverlight.js"></ script > < script type="text/javascript" src="jquery-1.6.4.min.js"></ script > < script type="text/javascript"> function onSilverlightError(sender, args) { var appSource = ""; if (sender != null && sender != 0) { appSource = sender.getHost().Source; } var errorType = args.ErrorType; var iErrorCode = args.ErrorCode; if (errorType == "ImageError" || errorType == "MediaError") { return; } var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n"; errMsg += "Code: " + iErrorCode + " \n"; errMsg += "Category: " + errorType + " \n"; errMsg += "Message: " + args.ErrorMessage + " \n"; if (errorType == "ParserError") { errMsg += "File: " + args.xamlFile + " \n"; errMsg += "Line: " + args.lineNumber + " \n"; errMsg += "Position: " + args.charPosition + " \n"; } else if (errorType == "RuntimeError") { if (args.lineNumber != 0) { errMsg += "Line: " + args.lineNumber + " \n"; errMsg += "Position: " + args.charPosition + " \n"; } errMsg += "MethodName: " + args.methodName + " \n"; } throw new Error(errMsg); } //加载Silverlight function loadSilverlight(url) { if (url.indexOf("#") == -1) {return;} var _param = url.split('#')[1]; var _sl = document.getElementById("sl"); var _xap = _param.split('|')[0] + ".xap"; var _page = _param.split('|')[1]; _sl.innerHTML = "< object data='data:application/x-silverlight-2,' type='application/x-silverlight-2' width='100%' height='100%'>< param name='source' value='ClientBin/" + _xap + "' />< param name='onError' value='onSilverlightError' />< param name='background' value='white' />< param name='minRuntimeVersion' value='4.0.50826.0' />< param name='autoUpgrade' value='true' />< param name='initParams' value='page=" + _page + "' />< a href='http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0' style='text-decoration: none'>< img src='http://go.microsoft.com/fwlink/?LinkId=161376' alt='Get Microsoft Silverlight' style='border-style: none' /></ a ></ object >"; } $().ready(function () { loadSilverlight(window.location.href); }) </ script > </ head > < body > < form id="form1" runat="server" style="height: 100%"> < div id="silverlightControlHost"> < div id="nav"> Silvelight分包以及SEO示例 (by 菩提树下的杨过 http://yjmyzz.cnblogs.com/):< br /> < a href="#Basic|Basic.City" onclick="loadSilverlight(this.href)">城市管理</ a > | < a href="#Basic|Basic.Airport" onclick="loadSilverlight(this.href)">航站管理</ a > | < a href="#User|User.User" onclick="loadSilverlight(this.href)">用户管理</ a > | < a href="#User|User.Organization" onclick="loadSilverlight(this.href)">组织机构管理</ a > </ div > < div id="sl"> < object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> < param name="source" value="ClientBin/Basic.xap" /> < param name="onError" value="onSilverlightError" /> < param name="background" value="white" /> < param name="minRuntimeVersion" value="4.0.50826.0" /> < param name="autoUpgrade" value="true" /> < param name="initParams" value="page=Basic.City" /> < a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" style="text-decoration: none"> < img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style: none" /> </ a > </ object > </ div > < iframe id="_sl_historyFrame" style="visibility: hidden; height: 0px; width: 0px; border: 0px"></ iframe > </ div > </ form > </ body > </ html > |