Windows Phone WCF 服务调用全攻略:从入门到实战踩坑
Windows Phone 虽然早已停止更新,但在早期移动开发中,它和 WCF(Windows Communication Foundation)的结合依然是不少老项目、教学案例和遗留系统的核心技术点。很多人搜“windows phone wcf”,就是想搞清楚怎么在 Windows Phone 应用里稳定调用 WCF 服务、处理数据传输、解决兼容和性能问题。下面从基础概念、实际搭建、调用步骤、常见故障到优化建议,一步步讲清楚,适合有一点 .NET 基础的开发者直接上手。
先搞懂 Windows Phone 和 WCF 的关系
Windows Phone 基于 Silverlight 运行时(WP7/WP8 主要是 Silverlight 版本),网络通信默认支持 HTTP、基本身份验证和部分 SOAP。WCF 是微软推出的统一通信框架,能创建 SOAP 服务、REST 风格服务,支持多种绑定(BasicHttpBinding、WebHttpBinding 等)。
在 Windows Phone 上直接调用 WCF 的优势很明显:
- 强类型代理,开发效率高。
- 支持数据契约(DataContract)、操作契约(OperationContract),序列化可靠。
- 能复用现有桌面或服务器端 WCF 服务,减少重复开发。
限制也不少:Windows Phone 不支持完整的 WCF 客户端配置(没有 system.serviceModel 完整支持),只能用 BasicHttpBinding 或自定义简单绑定,复杂的 WS-* 协议、消息安全、事务基本玩不了。异步调用是强制的,同步调用会卡死 UI。
准备工作:环境与工具
推荐环境:
- 开发机:Windows 7/8/10,安装 Visual Studio 2010/2012/2013(带 Windows Phone SDK)。
- 服务端:.NET Framework 4.0 或更高,IIS 或自托管。
- 模拟器:Windows Phone Emulator(记得开网络共享)。
- 真机调试需要开发者账号和解锁。
先确认服务端 WCF 能被外网或模拟器访问。防火墙放行端口,服务地址用 IP 而不是 localhost(模拟器访问本机要用特殊 IP 或主机名)。
第一步:创建可被 Windows Phone 调用的 WCF 服务
最稳妥的是用 BasicHttpBinding,它兼容性最好。
- 新建 WCF 服务应用程序(或 WCF 服务库 + 控制台/IIS 宿主)。
-
定义服务契约:
[ServiceContract] public interface IPhoneService { [OperationContract] string GetMessage(string name); [OperationContract] UserInfo GetUser(int id); }
[DataContract] public class UserInfo { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } }
3. 实现服务类,加上 ServiceBehavior 如果需要。
4. Web.config 关键配置(BasicHttpBinding 示例):
```xml
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttp" maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647"
maxArrayLength="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="YourNamespace.PhoneService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttp"
contract="YourNamespace.IPhoneService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
maxReceivedMessageSize 和 readerQuotas 一定要调大,否则 Windows Phone 传图片或列表时容易报错。发布到 IIS 后,用浏览器访问 .svc 地址确认 WSDL 能出来。
如果想更轻量,可以用 WebHttpBinding 做成 REST + JSON,Windows Phone 用 WebClient 或 HttpWebRequest 更灵活,但失去强类型代理的便利。
第二步:在 Windows Phone 项目里添加服务引用
- 新建 Windows Phone 应用(Silverlight)。
- 右键项目 → 添加服务引用 → 输入 WCF 地址(如 http://你的IP/Service.svc)。
- 点击“高级” → 取消勾选“复用类型”,生成完整代理。
- 命名空间自定义,比如 PhoneServiceReference。
生成后会得到一个客户端类(如 PhoneServiceClient)。注意:Windows Phone 的代理默认是异步的,方法名带 Async 和 Completed 事件。
第三步:实际调用代码(异步是关键)
页面加载或按钮点击时调用:
private void CallService()
{
var client = new PhoneServiceReference.PhoneServiceClient();
client.GetMessageCompleted += (s, e) =>
{
if (e.Error == null)
{
// 更新 UI,必须用 Dispatcher
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
txtResult.Text = e.Result;
});
}
else
{
// 处理错误
MessageBox.Show(e.Error.Message);
}
};
client.GetMessageAsync("WindowsPhone用户");
}
复杂对象同理,Completed 事件里拿 e.Result 即可。记得处理网络异常、超时和序列化失败。
如果服务需要认证,BasicHttpBinding 可加 TransportCredentialOnly 或用 MessageCredential,但 Windows Phone 支持有限,优先在 HTTP 头里手动加 Token。
常见问题与解决办法
1. 添加服务引用失败或生成代理报错
- 原因:服务端没开 metadata、防火墙、绑定不兼容。
- 解决:确认 mex 端点开启,用 svcutil.exe 手动生成代理类再拷贝进项目。地址用 IP,关闭模拟器代理。
2. 调用时出现 CommunicationException 或 EndpointNotFound
- 检查服务地址是否正确(模拟器访问本机服务用 http://192.168.x.x 或特殊映射)。
- 增大超时:client.Endpoint.Binding.SendTimeout = TimeSpan.FromMinutes(2);
- 网络权限:WMAppManifest.xml 里确认 ID_CAP_NETWORKING 已勾选。
3. 大数据或图片传输失败
- 调大 maxReceivedMessageSize、maxBufferSize。
- 考虑分块传输或改用 REST + 流式。
- 序列化用 DataContractJsonSerializer 有时更省流量。
4. 跨域或 HTTPS 问题 Windows Phone 对 HTTPS 证书校验严格,自签名证书需要额外处理(或改用 HTTP 测试)。生产环境务必正规证书。
5. 性能卡顿
- 所有网络操作必须异步,Completed 回调里切回 UI 线程。
- 避免在 UI 线程做反序列化。
- 缓存代理实例,不要每次 new。
- 开启 gzip 压缩(服务端配置,客户端用 WebClient 时手动处理)。
进阶优化与替代方案
- 安全加强:不要在 WCF 里传明文密码,用 Token + HTTPS。Windows Phone 可用 WebRequest 自定义头。
- 版本兼容:WP7 和 WP8 代理略有差异,WP8 可尝试更多绑定,但为了兼容尽量锁 BasicHttp。
- 调试技巧:用 Fiddler 抓包看真实请求;服务端开 includeExceptionDetailInFaults 方便看详细错误;模拟器网络不好时换真机。
- 如果 WCF 太重:改用 ASP.NET Web API(REST + JSON),Windows Phone 用 HttpClient 或 RestSharp 更轻更快,也是后来主流做法。遗留项目才死磕 WCF。
- 数据契约注意:循环引用、DateTime 时区、枚举都要处理好,否则反序列化直接炸。
实战小建议
开发时先本地 IIS 跑通,再用模拟器,最后真机。服务端日志一定要记,Windows Phone 端错误信息经常被包装得很模糊。项目收尾时把服务引用生成的 Reference.cs 检查一遍,删除多余 using,减小包体积。
Windows Phone + WCF 这套组合在 2011-2014 年非常常见,现在主要用于维护老系统或学习 .NET 移动通信原理。按上面步骤走,基本能把服务调通。配置绑定、异步回调、大小限制这三块是最容易踩坑的地方,重点盯紧就行。把服务地址、绑定参数、异常处理做成可配置,后期维护会轻松很多。

还没有评论,来说两句吧...