Client WCF DataContract has empty/null values from service

I have a simple WCF service that returns the time from the server. I've confirmed that data is being sent by checking with Fiddler. Here's the result object xml that my service sends.

    <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>

So, as far as I can tell, there's nothing wrong on the server end. It's receiving requests and returning results.

But on my silverlight client, all the members of the returned object are either null, blank or a default vaule. As you can see the server returns the current date and time. But in silverlight, theTime property on my object is set to 1/1/0001 12:00 AM (default value).

Sooo methinks that the DataContracts do not match up between the server and the silverlight client. Here's the DataContract for the server

    [DataContract]
 public class Time
 {
  [DataMember]
  public DateTime theTime { get; set; }
 }

Incredibly simple. And here's the datacontract on my silverlight client.

    [DataContract]
 public class Time
 {
  [DataMember]
  public DateTime theTime { get; set; }
 }

Literally the only difference is the namespaces within the application. But still the values being returned are null, empty or a .NET default.

Thanks for you help!

UPDATE

Here is the ClientBase that all my services run through. I read an excellent article here to construct it.

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, object state, 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, null, 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, null, Channel, 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; }
    }
}

Here is my interface

 [ServiceContract]      

    public interface ITestService
            {

                [OperationContract( AsyncPattern = true )]
                IAsyncResult BeginGetTime( AsyncCallback callback, object state );

                Time EndGetTime( IAsyncResult result );

            }

Now I have my service class that makes calls through my BaseService class using this interface.

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, null );
    }
}

Finally here is the code that actually calls everything and does the work.

    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 );

            } );

Whew....I hope no one is lost from all this code I posted :P

Answers


Because you don't set the Namespace property on your DataContractAttribute, the namespace will be sythesized from the .NET class/namespace. You can see this in the SOAP message example you posted:

http://schemas.datacontract.org/2004/07/TestService.DataObjects

In order to have the contracts be considered equal, you must set the Namespace property on the DataContract to the same value on both sides. That might look a little something like this:

[DataContract(Namespace="urn:my-test-namespace")]

Extending on Drew Marsh's correct answer (+1 - thx) I had a generated Service Reference which was working, but when I tried to use the Wcf Client Factory one implementing the correct interface (but the namespace was different) then I was experiencing the problem described.

I had no easy way to work out what the "correct" namespace should have been but simply copying the following attributes from the service reference's DataContract entity to the one in the Wcf Client Factory implementation solved the issue;

[System.Runtime.Serialization.DataContractAttribute(Name = "BOSPrice", Namespace = "http://schemas.datacontract.org/2004/07/BOSDataService")]
  [System.SerializableAttribute()]

Need Your Help

Update with where ANSI join syntax in PostgreSQL updates all rows

sql postgresql join

I'm trying to do an update with joins in the where clause. I understand with PostgreSQL there is a from clause that I can use with implicit joins like this:

Styling Individual Menu Items in WordPress

css wordpress menu

I'm trying to style my WordPress Menu. I want each menu item to have a different color and the background color of all the children on pages and posts must have the background color the same as the