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如下

ProductService

并在其中加入如下代码用于存储产品信息(包括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

AddWCFRef02

我们在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传过来的数据了

ProductDataUI

部署时由于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上了

代码下载:

posted @ 2009-02-26 16:02  ibillguo  阅读(4824)  评论(12编辑  收藏  举报