我有一个简单的WCF服务,从服务器返回时间.我已经确认通过与Fiddler进行检查来发送数据.这是我的服务发送的结果对象xml.
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <GetTimeResponse xmlns="http://tempuri.org/"> <GetTimeResult xmlns:a="http://schemas.datacontract.org/2004/07/TestService.DataObjects" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <a:theTime>2010-03-26T09:14:38.066372-06:00</a:theTime> </GetTimeResult> </GetTimeResponse> </s:Body> </s:Envelope>
所以,据我所知,服务器端没有任何错误.它正在接收请求并返回结果.
但是在我的silverlight客户端上,返回对象的所有成员都是null,空白或默认的vaule.您可以看到服务器返回当前日期和时间.但在silverlight中,我的对象的time属性设置为1/1/0001 12:00 AM(默认值).
在DataContracts与服务器和silverlight客户端之间不匹配的Sooo表示.这是服务器的DataContract
[DataContract] public class Time { [DataMember] public DateTime theTime { get; set; } }
难以置信的简单这是我的silverlight客户端上的datacontract.
[DataContract] public class Time { [DataMember] public DateTime theTime { get; set; } }
字面上唯一的区别是应用程序中的命名空间.但是,返回的值仍然为null,为空或.NET默认值.
感谢您的帮助!
UPDATE
这是我所有的服务都通过的ClientBase.我读了一个excellent article here来构造它.
public class ClientBase<T> where T :class { private T Channel { get; set; } private Type ContractType { get; set; } private ClientBase() { ContractType = typeof( T ); } public ClientBase(string endPointConfiguration) :this() { Channel = new ChannelFactory<T>( endPointConfiguration ).CreateChannel(); } public ClientBase( EndpointAddress address,Binding binding ):this() { Channel = new ChannelFactory<T>( binding,address ).CreateChannel(); } public void Begin(string methodName,object state,params object[] parameterArray) { Begin( methodName,null,state,parameterArray ); } public void Begin(string methodName,EventHandler<ClientEventArgs> callBack,params object[] parameterArray) { if(parameterArray != null) { Array.Resize(ref parameterArray,parameterArray.Length + 2); } else { parameterArray = new object[2]; } parameterArray[ parameterArray.Length - 1 ] = new ObjectClientState {CallBack = callBack,MethodName = methodName,UserState = state}; parameterArray[ parameterArray.Length - 2 ] = new AsyncCallback( OnCallBack ); ContractType.InvokeMember( "Begin" + methodName,System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public,Channel,parameterArray ); } private void OnCallBack(IAsyncResult result) { ObjectClientState state = result.AsyncState as ObjectClientState; if(state == null) return; Object obj = ContractType.InvokeMember( "End" + state.MethodName,System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public,new object[] {result} ); if(state.CallBack != null) { state.CallBack( this,new ClientEventArgs {Object = obj,UserState = state.UserState} ); } } public class ClientEventArgs : EventArgs { public object Object { get; set; } public object UserState { get; set; } public T LoadResult<T>() { if( Object is T ) return ( T ) Object; return default( T ); } } private class ObjectClientState { public EventHandler<ClientEventArgs> CallBack { get; set; } public string MethodName { get; set; } public object UserState { get; set; } } }
这是我的界面
[ServiceContract] public interface ITestService { [OperationContract( AsyncPattern = true )] IAsyncResult BeginGetTime( AsyncCallback callback,object state ); Time EndGetTime( IAsyncResult result ); }
现在我有我的服务类,通过我的BaseService类使用这个接口进行调用.
public class TestSiteService : ClientBase<ITestService> { public TestSiteService (string endPointConfiguration):base(endPointConfiguration) { } public TestSiteService ( EndpointAddress address,Binding binding ) : base( address,binding ) { } public void GetTime( EventHandler<ClientEventArgs> callBack ) { Begin( "GetTime",callBack,null ); } }
TestSiteService client = new TestSiteService ( new EndpointAddress( "http://localhost:3483/wcf/Service.svc" ),new BasicHttpBinding() ); client.GetTime( delegate( object res,ClientBase<ITestService>.ClientEventArgs e ) { Dispatcher.BeginInvoke( () => lblDisplay.Text = "Welcome " + e.LoadResult<Time>().theTime ); } );
我希望没有人丢失所有这些代码我发布:P
解决方法
因为您没有在DataContractAttribute上设置
the Namespace property,所以命名空间将从.NET类/命名空间进行协调.您可以在发布的SOAP消息示例中看到此信息:
http://schemas.datacontract.org/2004/07/TestService.DataObjects
为了使合同被视为相等,您必须将DataContract上的Namespace属性设置为两边的相同值.这可能看起来像这样一些东西:
[DataContract(Namespace="urn:my-test-namespace")]