微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

引用:Silverlight程序中动态设置WCF服务地址方法【附示例代码】http://www.aspxcs.net/HTML/2345222075.html#

Silverlight程序中动态设置WCF服务地址方法【附示例代码

发布时间:2010年05月22日 点击数: 491 次 佚名

Silverlight项目中添加服务引用后会在Silverlight项目中生成一个ServiceReferences.ClientConfig文件,这个文件中包含了引用服务的绑定(bindings)和终结点(Endpoint)的配置信息。下面是引用一个WCF服务后自动生成的配置信息:【示例源码下载

  1. <configuration>
  2. <system.serviceModel>
  3. <bindings>
  4. <basicHttpBinding>
  5. <binding name="BasicHttpBinding_IService1" maxBufferSize="2147483647"
  6. maxReceivedMessageSize="2147483647">
  7. <security mode="None" />
  8. </binding>
  9. </basicHttpBinding>
  10. </bindings>
  11. <client>
  12. <endpoint address="http://localhost:4177/Services/Service1.svc"
  13. binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
  14. contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" />
  15. </client>
  16. </system.serviceModel>
  17. </configuration>

在程序开发阶段,使用上面的配置信息不会有什么错误。在部署程序时,服务的地址通常和开发时使用的服务地址是不一样的,这时就需要修改上面的配置信息中的终结点的地址。但是Silverlight项目编译后会将ServiceReferences.ClientConfig嵌入到生成的xap文件中,这给修改带来了一定难度。关于动态设置服务终结点的地址Tim Heuer在Managing service references and endpoint configurations for Silverlight applications(http://zdd.me/managingendpoint)中介绍了几种方法,大家可以参考。下面是我在开发过程使用的两种方法
一、WCF和Silverlight位于同一站点
这种情况下可以通过Silverlight程序的Application.Current.Host.source和服务的相对地址来获得服务的地址。例如名为Service1.svc的服务放在网站的Services文件夹下,可以通过下面的代码取得它的地址:

  1. Uri serviceUri = new Uri(Application.Current.Host.source,"../Services/Service1.svc")

然后就可以通过在引用服务时自动生成的客户端代理类的重载构造函数

  1. public Service1Client(System.ServiceModel.Channels.Binding binding,System.ServiceModel.EndpointAddress remoteAddress) :
  2. base(binding,remoteAddress) {
  3. }

来新建一个类实例

  1. BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
  2. binding.MaxReceivedMessageSize = int.MaxValue;
  3. binding.MaxBufferSize = int.MaxValue;
  4. ServiceReference1.Service1Client client = new ServiceReference1.Service1Client(binding,new EndpointAddress(
  5. new Uri(Application.Current.Host.source,"../Services/Service1.svc")));

二、WCF位于单独的站点
这种情况下WCF的地址和网站的地址不一样了,因此就不能使用上面的方法了。这时可以将服务的地址配置在网站的web.config中,然后通过Silverlight的InitParams参数将服务地址传送到Silverlight程序中。下面是实现方法
1、在web.config中配置服务的地址

  1. <appSettings>
  2. <!-- 格式 服务名svc -->
  3. <add key="Service1svc" value="http://localhost:1468/Service1.svc"/>
  4. </appSettings>

2、通过使用Literal控件动态生成Silverlight的InitParams参数

然后在网页的Page_Load中从web.config获取到配置的服务地址并设置InitParams参数的值

  1. protected void Page_Load(object sender,EventArgs e)
  2. {
  3. if (!Page.IsPostBack)
  4. {
  5. Hashtable services = new Hashtable();
  6. foreach (string key in ConfigurationManager.AppSettings.AllKeys)
  7. {
  8. if (key.EndsWith("svc",StringComparison.CurrentCultureIgnoreCase))
  9. {
  10. services.Add(key,ConfigurationManager.AppSettings[key]);
  11. }
  12. }
  13. StringBuilder sb = new StringBuilder();
  14. foreach (string key in services.Keys)
  15. {
  16. sb.Append(string.Format(",{0}={1}",key,services[key]));
  17. }
  18. this.SLInitParams.Text = string.Format("<param name=/"InitParams/" value=/"{0}/" />",sb.ToString());
  19. }
  20. }

3、接着在Silverlight的Application_Startup中将参数中的值存储在ResourceDictionary,以备使用。然后在Silverlight项目中添加一个ServiceType枚举,用于列出在web.config中配置的所有服务地址的键值。
4、新建一下ServiceHelper泛型类,该类包括两个静态方法:1)GetInstance接受一个ServiceType类型的参数,通过反射创建一个服务的客户端代理类的实例;2)GetServiceAddress同样接受一个ServiceType类型的参数,获取服务的地址。

  1. public class ServiceHelper<T> where T : class
  2. {
  3. /// <summary>
  4. /// 根据服务类型新建一个服务实例
  5. /// </summary>
  6. /// <param name="serviceType">服务类型</param>
  7. /// <returns></returns>
  8. public static T GetInstance(ServiceType serviceType)
  9. {
  10. T _instance = null;
  11. string serviceUri = GetServiceAddress(serviceType);
  12. if (string.IsNullOrEmpty(serviceUri)) return null;
  13. object[] paras = new object[2];
  14. BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
  15. binding.MaxBufferSize = int.MaxValue;
  16. binding.MaxReceivedMessageSize = int.MaxValue;
  17. EndpointAddress address = new EndpointAddress(new Uri(serviceUri,UriKind.Absolute));
  18. paras[0] = binding;
  19. paras[1] = address;
  20. ConstructorInfo constructor = null;
  21. try
  22. {
  23. Type[] types = new Type[2];
  24. types[0] = typeof(System.ServiceModel.Channels.Binding);
  25. types[1] = typeof(System.ServiceModel.EndpointAddress);
  26. constructor = typeof(T).GetConstructor(types);
  27. }
  28. catch (Exception)
  29. {
  30. return null;
  31. }
  32. if (constructor != null)
  33. _instance = (T)constructor.Invoke(paras);
  34. return _instance;
  35. }
  36. /// <summary>
  37. /// 取得服务地址
  38. /// </summary>
  39. /// <param name="serviceType">服务类型</param>
  40. /// <returns></returns>
  41. public static string GetServiceAddress(ServiceType serviceType)
  42. {
  43. return App.Current.Resources[serviceType.ToString()].ToString();
  44. }
  45. }

然后就可以通过下面的代码创建一下服务的客户端代理类的实例了

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐