很少做手机开发,今天没事,做了个小小的实验,一般来讲,我学东西,只要能连上后台数据,基本上就可以了,因为前台很多东西要么不难,要么需要的是创意和美工,这都是我的薄弱之处,也就没兴趣深入了.
WCF大家估计都必须交熟悉,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Web; using System.Text; namespace WcfService4 { // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。 [ServiceContract] public interface IService1 { [OperationContract] string GetData(int value); [OperationContract] CompositeType GetDataUsingDataContract(CompositeType composite); // TODO: 在此添加您的服务操作 } // 使用下面示例中说明的数据约定将复合类型添加到服务操作。 [DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello "; [DataMember] public bool BoolValue { get { return boolValue; } set { boolValue = value; } } [DataMember] public string StringValue { get { return stringValue; } set { stringValue = value; } } } }
直接在客户端添加服务引用,是一种方法,但这种方法有个问题,就是如果有复杂对象,就会出问题,没法生成服务所需要的代理代码.解决对象穿越问题,当然可以自己利用序列化和反序列化,中间利用字符串来传递,但这种方法工作量比较大.另外一种方式就是共享service服务接口和实体,这个非常方便,但问题是winphone和一般桌面的环境还是差很远,在wp7中引用实体解决还好点,要引用服务段的wcf契约接口问题很大,而且wp7里的servicemodel的版本和服务端的版本也不一致,调用也非常麻烦,最后找到一种利用silverlight的wcf ria service生成客户端代码工具来生成客户端代理得以解决,一般命令为:SlSvcUtil.exe 服务地址.把生成的文件引入到wp7工程即可用.生成的代码如下,其实大家可以学习它生成的代码,自己整一个通用的方法也是可行的:
//------------------------------------------------------------------------------ // <auto-generated> // 此代码由工具生成。 // 运行时版本:4.0.30319.17379 // // 对此文件的更改可能会导致不正确的行为,并且如果 // 重新生成代码,这些更改将会丢失。 // </auto-generated> //------------------------------------------------------------------------------ // // This code was auto-generated by SlSvcUtil, version 5.0.61118.0 // namespace WcfService4 { using System.Runtime.Serialization; [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] [System.Runtime.Serialization.DataContractAttribute(Name="CompositeType", Namespace="http://schemas.datacontract.org/2004/07/WcfService4")] public partial class CompositeType : object { private bool BoolValueField; private string StringValueField; [System.Runtime.Serialization.DataMemberAttribute()] public bool BoolValue { get { return this.BoolValueField; } set { this.BoolValueField = value; } } [System.Runtime.Serialization.DataMemberAttribute()] public string StringValue { get { return this.StringValueField; } set { this.StringValueField = value; } } } } [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] [System.ServiceModel.ServiceContractAttribute(ConfigurationName="IService1")] public interface IService1 { [System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action="http://tempuri.org/IService1/GetData", ReplyAction="http://tempuri.org/IService1/GetDataResponse")] System.IAsyncResult BeginGetData(int value, System.AsyncCallback callback, object asyncState); string EndGetData(System.IAsyncResult result); [System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action="http://tempuri.org/IService1/GetDataUsingDataContract", ReplyAction="http://tempuri.org/IService1/GetDataUsingDataContractResponse")] System.IAsyncResult BeginGetDataUsingDataContract(WcfService4.CompositeType composite, System.AsyncCallback callback, object asyncState); WcfService4.CompositeType EndGetDataUsingDataContract(System.IAsyncResult result); } [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] public interface IService1Channel : IService1, System.ServiceModel.IClientChannel { } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] public partial class GetDataCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { private object[] results; public GetDataCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState) { this.results = results; } public string Result { get { base.RaiseExceptionIfNecessary(); return ((string)(this.results[0])); } } } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] public partial class GetDataUsingDataContractCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { private object[] results; public GetDataUsingDataContractCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState) { this.results = results; } public WcfService4.CompositeType Result { get { base.RaiseExceptionIfNecessary(); return ((WcfService4.CompositeType)(this.results[0])); } } } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] public partial class Service1Client : System.ServiceModel.ClientBase<IService1>, IService1 { private BeginOperationDelegate onBeginGetDataDelegate; private EndOperationDelegate onEndGetDataDelegate; private System.Threading.SendOrPostCallback onGetDataCompletedDelegate; private BeginOperationDelegate onBeginGetDataUsingDataContractDelegate; private EndOperationDelegate onEndGetDataUsingDataContractDelegate; private System.Threading.SendOrPostCallback onGetDataUsingDataContractCompletedDelegate; private BeginOperationDelegate onBeginOpenDelegate; private EndOperationDelegate onEndOpenDelegate; private System.Threading.SendOrPostCallback onOpenCompletedDelegate; private BeginOperationDelegate onBeginCloseDelegate; private EndOperationDelegate onEndCloseDelegate; private System.Threading.SendOrPostCallback onCloseCompletedDelegate; public Service1Client() { } public Service1Client(string endpointConfigurationName) : base(endpointConfigurationName) { } public Service1Client(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public Service1Client(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public Service1Client(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public System.Net.CookieContainer CookieContainer { get { System.ServiceModel.Channels.IHttpCookieContainerManager httpCookieContainerManager = this.InnerChannel.GetProperty<System.ServiceModel.Channels.IHttpCookieContainerManager>(); if ((httpCookieContainerManager != null)) { return httpCookieContainerManager.CookieContainer; } else { return null; } } set { System.ServiceModel.Channels.IHttpCookieContainerManager httpCookieContainerManager = this.InnerChannel.GetProperty<System.ServiceModel.Channels.IHttpCookieContainerManager>(); if ((httpCookieContainerManager != null)) { httpCookieContainerManager.CookieContainer = value; } else { throw new System.InvalidOperationException("Unable to set the CookieContainer. Please make sure the binding contains an HttpC" + "ookieContainerBindingElement."); } } } public event System.EventHandler<GetDataCompletedEventArgs> GetDataCompleted; public event System.EventHandler<GetDataUsingDataContractCompletedEventArgs> GetDataUsingDataContractCompleted; public event System.EventHandler<System.ComponentModel.AsyncCompletedEventArgs> OpenCompleted; public event System.EventHandler<System.ComponentModel.AsyncCompletedEventArgs> CloseCompleted; [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] System.IAsyncResult IService1.BeginGetData(int value, System.AsyncCallback callback, object asyncState) { return base.Channel.BeginGetData(value, callback, asyncState); } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] string IService1.EndGetData(System.IAsyncResult result) { return base.Channel.EndGetData(result); } private System.IAsyncResult OnBeginGetData(object[] inValues, System.AsyncCallback callback, object asyncState) { int value = ((int)(inValues[0])); return ((IService1)(this)).BeginGetData(value, callback, asyncState); } private object[] OnEndGetData(System.IAsyncResult result) { string retVal = ((IService1)(this)).EndGetData(result); return new object[] { retVal}; } private void OnGetDataCompleted(object state) { if ((this.GetDataCompleted != null)) { InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state)); this.GetDataCompleted(this, new GetDataCompletedEventArgs(e.Results, e.Error, e.Cancelled, e.UserState)); } } public void GetDataAsync(int value) { this.GetDataAsync(value, null); } public void GetDataAsync(int value, object userState) { if ((this.onBeginGetDataDelegate == null)) { this.onBeginGetDataDelegate = new BeginOperationDelegate(this.OnBeginGetData); } if ((this.onEndGetDataDelegate == null)) { this.onEndGetDataDelegate = new EndOperationDelegate(this.OnEndGetData); } if ((this.onGetDataCompletedDelegate == null)) { this.onGetDataCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnGetDataCompleted); } base.InvokeAsync(this.onBeginGetDataDelegate, new object[] { value}, this.onEndGetDataDelegate, this.onGetDataCompletedDelegate, userState); } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] System.IAsyncResult IService1.BeginGetDataUsingDataContract(WcfService4.CompositeType composite, System.AsyncCallback callback, object asyncState) { return base.Channel.BeginGetDataUsingDataContract(composite, callback, asyncState); } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] WcfService4.CompositeType IService1.EndGetDataUsingDataContract(System.IAsyncResult result) { return base.Channel.EndGetDataUsingDataContract(result); } private System.IAsyncResult OnBeginGetDataUsingDataContract(object[] inValues, System.AsyncCallback callback, object asyncState) { WcfService4.CompositeType composite = ((WcfService4.CompositeType)(inValues[0])); return ((IService1)(this)).BeginGetDataUsingDataContract(composite, callback, asyncState); } private object[] OnEndGetDataUsingDataContract(System.IAsyncResult result) { WcfService4.CompositeType retVal = ((IService1)(this)).EndGetDataUsingDataContract(result); return new object[] { retVal}; } private void OnGetDataUsingDataContractCompleted(object state) { if ((this.GetDataUsingDataContractCompleted != null)) { InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state)); this.GetDataUsingDataContractCompleted(this, new GetDataUsingDataContractCompletedEventArgs(e.Results, e.Error, e.Cancelled, e.UserState)); } } public void GetDataUsingDataContractAsync(WcfService4.CompositeType composite) { this.GetDataUsingDataContractAsync(composite, null); } public void GetDataUsingDataContractAsync(WcfService4.CompositeType composite, object userState) { if ((this.onBeginGetDataUsingDataContractDelegate == null)) { this.onBeginGetDataUsingDataContractDelegate = new BeginOperationDelegate(this.OnBeginGetDataUsingDataContract); } if ((this.onEndGetDataUsingDataContractDelegate == null)) { this.onEndGetDataUsingDataContractDelegate = new EndOperationDelegate(this.OnEndGetDataUsingDataContract); } if ((this.onGetDataUsingDataContractCompletedDelegate == null)) { this.onGetDataUsingDataContractCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnGetDataUsingDataContractCompleted); } base.InvokeAsync(this.onBeginGetDataUsingDataContractDelegate, new object[] { composite}, this.onEndGetDataUsingDataContractDelegate, this.onGetDataUsingDataContractCompletedDelegate, userState); } private System.IAsyncResult OnBeginOpen(object[] inValues, System.AsyncCallback callback, object asyncState) { return ((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(callback, asyncState); } private object[] OnEndOpen(System.IAsyncResult result) { ((System.ServiceModel.ICommunicationObject)(this)).EndOpen(result); return null; } private void OnOpenCompleted(object state) { if ((this.OpenCompleted != null)) { InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state)); this.OpenCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(e.Error, e.Cancelled, e.UserState)); } } public void OpenAsync() { this.OpenAsync(null); } public void OpenAsync(object userState) { if ((this.onBeginOpenDelegate == null)) { this.onBeginOpenDelegate = new BeginOperationDelegate(this.OnBeginOpen); } if ((this.onEndOpenDelegate == null)) { this.onEndOpenDelegate = new EndOperationDelegate(this.OnEndOpen); } if ((this.onOpenCompletedDelegate == null)) { this.onOpenCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnOpenCompleted); } base.InvokeAsync(this.onBeginOpenDelegate, null, this.onEndOpenDelegate, this.onOpenCompletedDelegate, userState); } private System.IAsyncResult OnBeginClose(object[] inValues, System.AsyncCallback callback, object asyncState) { return ((System.ServiceModel.ICommunicationObject)(this)).BeginClose(callback, asyncState); } private object[] OnEndClose(System.IAsyncResult result) { ((System.ServiceModel.ICommunicationObject)(this)).EndClose(result); return null; } private void OnCloseCompleted(object state) { if ((this.CloseCompleted != null)) { InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state)); this.CloseCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(e.Error, e.Cancelled, e.UserState)); } } public void CloseAsync() { this.CloseAsync(null); } public void CloseAsync(object userState) { if ((this.onBeginCloseDelegate == null)) { this.onBeginCloseDelegate = new BeginOperationDelegate(this.OnBeginClose); } if ((this.onEndCloseDelegate == null)) { this.onEndCloseDelegate = new EndOperationDelegate(this.OnEndClose); } if ((this.onCloseCompletedDelegate == null)) { this.onCloseCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnCloseCompleted); } base.InvokeAsync(this.onBeginCloseDelegate, null, this.onEndCloseDelegate, this.onCloseCompletedDelegate, userState); } protected override IService1 CreateChannel() { return new Service1ClientChannel(this); } private class Service1ClientChannel : ChannelBase<IService1>, IService1 { public Service1ClientChannel(System.ServiceModel.ClientBase<IService1> client) : base(client) { } public System.IAsyncResult BeginGetData(int value, System.AsyncCallback callback, object asyncState) { object[] _args = new object[1]; _args[0] = value; System.IAsyncResult _result = base.BeginInvoke("GetData", _args, callback, asyncState); return _result; } public string EndGetData(System.IAsyncResult result) { object[] _args = new object[0]; string _result = ((string)(base.EndInvoke("GetData", _args, result))); return _result; } public System.IAsyncResult BeginGetDataUsingDataContract(WcfService4.CompositeType composite, System.AsyncCallback callback, object asyncState) { object[] _args = new object[1]; _args[0] = composite; System.IAsyncResult _result = base.BeginInvoke("GetDataUsingDataContract", _args, callback, asyncState); return _result; } public WcfService4.CompositeType EndGetDataUsingDataContract(System.IAsyncResult result) { object[] _args = new object[0]; WcfService4.CompositeType _result = ((WcfService4.CompositeType)(base.EndInvoke("GetDataUsingDataContract", _args, result))); return _result; } } }
调用奇简单:
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) { BasicHttpBinding theBinding = new BasicHttpBinding(); theBinding.MaxReceivedMessageSize = int.MaxValue; theBinding.MaxBufferSize = int.MaxValue; Service1Client theC = new Service1Client(theBinding, new EndpointAddress("http://localhost:1599/Service1.svc")); theC.GetDataCompleted += new EventHandler<GetDataCompletedEventArgs>(theC_GetDataCompleted); theC.GetDataUsingDataContractCompleted += new EventHandler<GetDataUsingDataContractCompletedEventArgs>(theC_GetDataUsingDataContractCompleted); theC.GetDataAsync(100); WcfService4.CompositeType theC1 = new WcfService4.CompositeType(){ StringValue="xxxxxx", BoolValue=true}; theC.GetDataUsingDataContractAsync(theC1); } void theC_GetDataUsingDataContractCompleted(object sender, GetDataUsingDataContractCompletedEventArgs e) { this.listBox1.Items.Add(e.Result.StringValue); } void theC_GetDataCompleted(object sender, GetDataCompletedEventArgs e) { this.listBox1.Items.Add(e.Result); }
PS:wp7界面采用的也是wpf,所以很多绑定之类的技巧,也可以参考我前面的博文(silverlight,wpf).一个感觉就是wp7的学习成本对于微软体系的程序员来说很容易,这也是微软的强大之处,你只要学会了微软的这套东西,在手机,桌面,嵌入式,web端等开发之间进行转换很容易.