创建Silverlight应用程序项目的时候,VS会问你 是调试的时候生成测试页来承载Silverlight还是自动创建个ASP.NET项目来承载Silverlight, 有什么区别呢 ?如果你只是做Silverlight的界面和客户端的交互效果,用单独的测试页来承载就可以了,这样方便调试,按个CTRL+F5就OK,但是如果你要用到WCF,或者通过ASP.NET做些动态的事情,那么就用ASP.NET项目来承载吧,这样可以尽可能的模拟出将Silverlight承载到网站后的效果。
创建Silverlight后,你可以看到项目里有两个XAML文件并相应的对应了.CS文件, 一个是APP.XAML另一个是Page.XAML,APP.XAML.CS的构造函数是初始化Silverlight项目的,接下来
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new page();
}
可以看到 new 后面的就是Page.xaml.cs所在的类。他的意思当然就是创建Page示例,这样你的Page就被实例化出来了,很像WINFORM吧。
之后的事情,个人认为开发过.NET的人应该都驾轻就熟了。需要注意的是,跟开发ASP.NET不同, Silverlight的所有代码是在客户端运行的,对于很多开发惯了ASP.NET的人来说可能一下子不习惯,不过如果你是做WINFORM的,那就当我没说。
试着写一个小程序来玩玩吧。
东西做好了,当然那就需要编译。Silverlight在生成后会在BIN下生成一个APPMAINFEST.XAML,这是一些配置比如DLL的路径,一个DLL,不用说了,逻辑代码都在这。另外会有一个XAP,这是什么,其实就是刚才说的那两个文件的一个压缩包,可以ZIP RAR工具打开,他只是将后缀作为XAP,这样在页面上<object>调用的时候SOURCE就会指向XAP这个包。
就这么简单,在WEB上用<object>承载这个生成出来的XAP包就可以显示Silverlight了。
似乎太没什么含量,感觉不出Silverlight的魅力。
那么就尝试做个应用了WCF的Silverlight吧。
WCF是什么?根据我了解的资料,WCF是一个统一的类似WEBSERVICE的解决方案,WEBSERVICE是WCF的一个子集。
他提供了更多更强的服务方案。
具体资料可以在MSDN上找到,废话不多说了。
引用WCF等过程与以前引用WEBSERIVCE差不多,摸索下很快就了解了。
这里提一下需要注意的地方。
在引用 WCF后,Silverlight项目里会生成一个ClientConfig文件,如果WCF项目是单独的,这个ClientConfig文件里不会写入任何东西,你只会看见一个配置跟节点。
但是如果你的WCF是创建在某个ASP.NET项目里,这时候生成出来的ClientConfig文件里会有很多配置,例如绑定方式和服务ENDPOINT(服务提供的地址)。
以上绿色文字的地方是我之前的理解错误,ServiceReferences.ClientConfig内是否自动生成配置信息是要看Silverlight引用的WCF是否启用了Silverlight功能,而不是看WCF是单独的项目还是在Web项目中的其中一项。所以在当我们在在项目中创建一个“启用Silverlight功能的WCF”后,在Silverlight项目中引用它时,ServiceReferences.ClientConfig文件就会自动配置出该引用的终节点和绑定。
实际上引用WCF之后,项目里只是创建了一个WCF所提供服务的类的结构,至于如何去绑定,去哪里请求服务,都是由配置的Binding方式和ENDPOINTADDRESS来决定。
为什么引用一个单独的WCF项目时不生成配置呢?因为在编码过程中,程序员可以制定BIND和ENDPOINT,所以,个人认为MS是为了让你的应用程序更加灵活,所以直接引用独立的WCF项目是不会生成CLIENTCONFIG的配置的,然而,如果你的WCF服务是来自一个ASP.NET项目的话,那么Silverlight项目会认为你将会把Silverlight承载到这个ASP.NET中的某页去,因此就将BIND和ENDPOINT直接配置到了CLIENTCONFIG中。当然,及时配置到了CLIENTCONFIG,在编码中仍然可以指定BIND和ENDPOINT来覆盖CLIENTCONFIG中的配置。
Silverlight在调用WCF服务是通过异步调用,因此代码类似这样:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Binding binding = new BasicHttpBinding();
EndpointAddress endPoint = new EndpointAddress(
"http://localhost:52424/Blog.svc");
BlogClient client = new BlogClient(binding, endPoint);
client.GetPostsCompleted += new EventHandler<GetPostsCompletedEventArgs>(client_GetPostsCompleted);
client.GetPostsAsync();
}
void client_GetPostsCompleted(object sender, GetPostsCompletedEventArgs e)
{
if (e.Error == null)
{
Posts.ItemsSource = e.Result;
}
}
可以看到,当你在WCF创建了一个类,调用的时候,该类会被命名成[类名]+Client,所以,看到别人调用的时候有个XXCLIENT,不要奇怪为什么上下文找不到其定义。
之后,类中的方法也会成为 方法+ASYNC 这是异步方法,在Silverlight中引用WCF就会出现,而在ASP.NET项目中引用则没有。
WCF被Silverlight引用后,会生成一个事件,对应方法 方法名+Compeleted,在事件上绑定好处理函数,就完成了异步调用并异步返回了。
很简单吧,比起AJAX来说,实在是方便很多。
注意看的朋友会发现 这里定义了个 Binding 类型的binding实例,和一个EndpointAddress 类型的endPoint,这就是之前我提到可以在编码中手工指定 bind方法和Endpoint的地方,如果 ClientConfig里配置好了这两个参数,你也可以这样写
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
BlogClient client = new BlogClient();
client.GetPostsCompleted += new EventHandler<GetPostsCompletedEventArgs>(client_GetPostsCompleted);
client.GetPostsAsync();
}
当然,及时ClientConfig里配置好了,也可以通过编码的时候指定来更改这两个参数。
如果完全理解了Silverlight+WCF怎么做,我想你可以轻松的完成一个小示例来享受下Silverlight的魅力。
但是可能大多数人在做Silverlight+WCF的时候会遇到一些郁闷的问题,典型的就是跨域访问的问题。
WCF比 WS考虑得要周全些了,为了禁止外部的非法调用,WCF默认只能是同域才可访问,我们在开发的时候,如果WCF是单独的项目,那么调试时,WCF的路径可能是 http://localhost:1234/test.svc。而用来承载Silverlight的ASP.NET路径则可能是 http://localhost:4321/xx.aspx ,这样是会被认为是两个不同的域,因此你的Silverlight将会出现跨域访问的报错,如果解决呢?没什么特的,部署好,或是将两个项目都生成好之后部署到IIS里,或是将 WCF项目移植到 ASP.NET项目中。
OK!
基本上来说,Silverlight以及 Silverlight+WCF的开发解决方案就如此了。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/banmuhuangci/archive/2009/04/24/4106201.aspx