惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
L
LangChain Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
罗磊的独立博客
J
Java Code Geeks
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 叶小钗
小众软件
小众软件
博客园 - Franky
D
Docker
Google DeepMind News
Google DeepMind News
Microsoft Azure Blog
Microsoft Azure Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
U
Unit 42
宝玉的分享
宝玉的分享
C
Check Point Blog
B
Blog
V
V2EX
博客园 - 三生石上(FineUI控件)
MyScale Blog
MyScale Blog
The Cloudflare Blog
博客园 - 聂微东
博客园_首页
Engineering at Meta
Engineering at Meta

博客园 - jv9

SharePoint 2013技巧分享系列 - 同步Exchange显示高清用户照片 SharePoint 2013常用开发工具分享 SharePoint 2013技巧分享系列 - Active Directory同步显示用户照片 SharePoint 2013技巧分享系列 - 隐藏Blog和Apps左侧导航菜单 常用Git代码托管服务分享 Microsoft Client Development MVP 2013 - 2014 车祸 Windows 8实例教程系列 - 数据绑定高级实例 Windows 8实例教程系列 - 数据绑定基础实例 Windows 8应用实例解析 - WinRT下创建GIF动画(Flipflop) Windows 8实例教程系列 - 布局控制 Windows 8实例教程系列 - 自定义应用风格 轻松搭建Windows8云平台开发环境 对比Windows 8模拟器(Simulator)和Windows Phone仿真器(Emulator) Windows8/Silverlight/WPF/WP7/HTML5周学习导读(1月28日-2月3日) Windows 8应用开发书籍汇总 心境 Windows8/Silverlight/WPF/WP7/HTML5周学习导读(1月7日-1月14日) Windows8/Silverlight/WPF/WP7/HTML5周学习导读(1月1日-1月6日)
Silverlight动态设置WCF服务Endpoint
jv9 · 2013-02-02 · via 博客园 - jv9

2013-02-02 05:57  jv9  阅读(2634)  评论()    收藏  举报

去年12月收到一位朋友的邮件,咨询Silverlight使用WCF服务,应用部署后一直无法访问的问题,通过几次交流,才发现在他的项目中,全部使用静态URL作为WCF服务的Endpoint地址,后来修改为动态地址后,问题解决。本篇简单介绍如何创建动态WCF Endpoint。

Silverlight项目中通过WCF服务进行客户端与服务器端数据交互,其方法是在Silverlight客户端添加服务引用(Service Reference),Silverlight会在客户端项目中生成一个名为ServiceReference.ClientConfig的配置文件。该配置文件中包含有WCF服务的Endpoint URL地址,而该地址将指引Silverlight客户端服务请求到对应服务器端服务接口。默认情况下,客户端生成的Endpoint地址为localhost,当应用发布时,该地址将随着Web服务器的配置不同而改变。

作为默认设置,每次Web服务器配置切换,开发人员不得不手动修改WCF服务配置,Silverlight应用无法完全依赖于ServiceReference.ClientConfig配置。这样不仅增加了维护成本,而且为代码维护添加难度。 

首先在项目中添加WCF服务,Silverlight 默认生成ServiceReference.ClientConfig文件,从配置文件中可以看出,Endpoint都是指向本地。

<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_ProxyService" maxBufferSize="2147483647"
                    maxReceivedMessageSize="2147483647">
                    <security mode="None" />
                </binding>
                <binding name="BasicHttpBinding_WidgetService" maxBufferSize="2147483647"
                    maxReceivedMessageSize="2147483647">
                    <security mode="None" />
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost/WCFTest/Proxy.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ProxyService"
                contract="WCFTestProxy.ProxyService" name="BasicHttpBinding_ProxyService" />
            <endpoint address="http://localhost/WCFTest/Widget.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_WidgetService"
                contract="WCFTestWidgetService.WidgetService" name="BasicHttpBinding_WidgetService" />
        </client>
    </system.serviceModel>
</configuration>

为了实现动态设置Endpoint,下面将创建一个辅助类DynamicEndpointHelper,

public class DynamicEndpointHelper
{
    // BaseUrl是部署服务的Web服务器地址
    private const string BaseUrl = "http://localhost/WCFTest/";

    public static string ResolveEndpointUrl(string endpointUrl, string xapPath)
    {
        string baseUrl = xapPath.Substring(0, xapPath.IndexOf("ClientBin"));
        string relativeEndpointUrl = endpointUrl.Substring(BaseUrl.Length);
        string dynamicEndpointUrl = baseUrl + relativeEndpointUrl;
        return dynamicEndpointUrl;
    }
}

而在Silverlight客户端,可以通过后台代码实现动态设置Endpoint,

private WCFTestProxy.ProxyServiceClient GetProxyService()
{
    WCFTestProxy.ProxyServiceClient service = new WCFTestProxy.ProxyServiceClient();
    service.Endpoint.Address = new EndpointAddress(
        DynamicEndpointHelper.ResolveEndpointUrl(service.Endpoint.Address.Uri.ToString(),
        App.Current.Host.Source.ToString()));
    return service;
}

在创建完成代理客户端服务后,Endpoint地址将指向当前运行的Web地址。值得注意的是,该方法仅能支持应用与服务在相同域中,如果服务在不同的域中,必须进行跨域设置才能完成动态设置。