Silverlight专题(16)- 动态设置WCF Service配置信息
问题:
在Silverlight中是使用ServiceReferences.ClientConfig文件来保存和查看WCF服务的相对信息的
而ServiceReferences.ClientConfig又是包含在.xap文件中的
这样就导致如果您的Silverlight工程有用到WCF服务就需要在每次部署到不同网站的时候重新更改下WCF的配置并重新编译
而且这个重新配置的过程又往往可能需要Visual Studio 2008的帮助来重新链接WCF服务
而且对于有些部署的服务器就可能非常不现实了(有的服务器要求系统干净,不允许安装其他软件)
那么怎么办呢?
解决方案:
首先让我们来创建一个含有WCF Service的Silverlight工程
并在Web工程中添加一个Silverlight-enabled WCF Service如下
并在其中加入如下代码用于存储产品信息(包括Name名字、Description描述、Price价格):
1: [DataContract]
2: public class ProductInfo
3: {
4: [DataMember]
5: public string Name;
6:
7: [DataMember]
8: public double Price;
9:
10: [DataMember]
11: public string Description;
12: }
而其OperateContract为
1: [ServiceContract(Namespace = "")]
2: [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
3: public class ProductService
4: {
5: [OperationContract]
6: public List<ProductInfo> RetreiveData()
7: {
8: List<ProductInfo> products=new List<ProductInfo>();
9: for (int i = 0; i < 8; i++)
10: {
11: products.Add(new ProductInfo()
12: {
13: Name = "Product " + (i + 1),
14: Price = 30.5*(i+1),
15: Description = "Product "+(i+1)+" for test"
16: }
17: );
18: }
19: // Add your operation implementation here
20: return products;
21: }
22: }
用来以WCF Service的形式将数据库中的数据(这里为方便期间用了伪数据)传给Silverlight客户端
首先给Silverlight工程添加Service References
我们在Silverlight客户端这边以ListBox的形式呈现出来,定义如下(Page.xaml文件中)
1: <ListBox x:Name="ProductLBCtl" HorizontalAlignment="Center" VerticalAlignment="Top" Background="Transparent" BorderThickness="0">
2: <ListBox.ItemTemplate>
3: <DataTemplate>
4: <StackPanel Orientation="Horizontal">
5: <ContentPresenter Content="{Binding Name}" Margin="10,0"/>
6: <ContentPresenter Content="{Binding Description}" Margin="10,0"/>
7: <ContentPresenter Content="{Binding Price}" Margin="10,0"/>
8: </StackPanel>
9: </DataTemplate>
10: </ListBox.ItemTemplate>
11: </ListBox>
获取WCF Service的数据信息如下(Page.xaml.cs中)
1: public Page()
2: {
3: InitializeComponent();
4: this.Loaded += new RoutedEventHandler(Page_Loaded);
5: }
6:
7: void Page_Loaded(object sender, RoutedEventArgs e)
8: {
9: ProductServiceClient client=new ProductServiceClient();
10: this.Cursor = Cursors.Hand;
11: client.RetreiveDataAsync();
12: client.RetreiveDataCompleted += (sender2, e2) =>
13: {
14: if (e2.Cancelled == false && e2.Error == null)
15: {
16: ObservableCollection<ProductInfo> products = e2.Result;
17: this.ProductLBCtl.ItemsSource = products;
18: this.Cursor = Cursors.Arrow;
19: }
20: };
21: }
这样我们就可以获得到WCF Service传过来的数据了
部署时由于WCF Service的部署地址不同,将需要我们重新索引,并编译这个程序,非常繁琐
你可以采用如下的动态配置的方式一举解决这个问题:
删除ServiceReferences.ClientConfig文件,并在Silverlight 工程下添加一个类文件(Class File)ServiceUtil.cs如下
1: public static ProductServiceClient GetDynamicClient()
2: {
3: BasicHttpBinding binding = new BasicHttpBinding(
4: Application.Current.Host.Source.Scheme.Equals("https", StringComparison.InvariantCultureIgnoreCase)
5: ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.None);
6: binding.MaxReceivedMessageSize = int.MaxValue;
7: binding.MaxBufferSize = int.MaxValue;
8: return new ProductServiceClient(binding, new EndpointAddress(
9: new Uri(Application.Current.Host.Source, "../ProductService.svc")));
10: }
上述就是通过动态的形式获取得到ProductService了
修改Page.xaml.cs文件如下
1: void Page_Loaded(object sender, RoutedEventArgs e)
2: {
3: ProductServiceClient client = ServiceUtil.GetDynamicClient();//动态获取ProductServiceClient
4: this.Cursor = Cursors.Hand;
5: client.RetreiveDataAsync();
6: client.RetreiveDataCompleted += (sender2, e2) =>
7: {
8: if (e2.Cancelled == false && e2.Error == null)
9: {
10: ObservableCollection<ProductInfo> products = e2.Result;
11: this.ProductLBCtl.ItemsSource = products;
12: this.Cursor = Cursors.Arrow;
13: }
14: };
15: }
这样大家就可以在不用修改的情况下非常便捷的部署到IIS或者Apache上了