0
votes

I have a WCF service that passes back and forth the following DataContracts:

[DataContract]
public class RequestWrapper
{
    [DataMember]
    public FooDataContract FooDataContract;
}

[DataContract]
public class ResponseWrapper
{
    [DataMember]
    public FooDataContract FooDataContract;
}

[DataContract]
public class FooDataContract
{
    public FooDataContract(string data, Guid id)
    {
        Data = data;
        ID = id;
    }

    [DataMember]
    public string Data { get; set; }

    [DataMember]
    public Guid ID { get; set; }
}

It's called via a proxy class like this:

void CallService(string data)
{
    var id = Guid.NewGuid();

    var response = proxy.CallService(new RequestWrapper
    {
        new FooDataContract(data, id);
    });
}

This is then passed (over the service) to the database via a repository using EF:

public void RepoMethod(FooDataContract foo)
{
    var guid = foo.ID; // - Breakpoint here shows all zeros!

    efContext.DoSomething(foo.Data, foo.ID);
}

Here's the service call:

public ResponseWrapper CallService(RequestWrapper request)
{
    var foo = request.FooDataContract;
    repository.RepoMethod(foo);

    var response = new ResponseWrapper{ FooDataContract = foo };
    return response;
}

Here's the proxy:

public class Proxy : IMyService
{
    static readonly ChannelFactory<IMyService> channelFactory =
        new ChannelFactory<IMyService>("IMyService");

    ResponseWrapper CallService(RequestWrapper request)
    {
        return channelFactory.UseService(s => s.CallService(request));
    }
}

internal static class UseServiceFunction
{
    internal static R UseService<T, R>
            (this ChannelFactory<T> channelFactory, Func<T, R> useService)
    {
        var service = channelFactory.CreateChannel();
        try
        {
            R response = useService(service);
            return response;
        }
        finally
        {
            var channel = service as ICommunicationObject;
            try
            {
                if (channel.State != CommunicationState.Faulted) channel.Close();
            }
            catch { channel.Abort(); }
        }
    }
}

I've put a watch on the Guid in the VS debugger. When the service is called from a client web application, the generated Guid is a valid Guid of seemingly random hex characters. Great, that's working.

But when the data is serialized, goes over the wire, and comes out the other side (in my repository), the Guid is all zeros!

I've double, triple checked that the Guid is indeed marked with the [DataMember] attribute. I'm wondering if the extra layer of DataContract (how a FooDataContract is wrapped with the RequestWrapper data contract) is causing a serialization issue?

2
Can you provide the code in your WCF service that calls the repo method?Suhas

2 Answers

1
votes

I think your problem here is that the constructor you've made in your DataContract class doesn't get passed to the proxy on the client side. WSDL won't know anything about this. Think of your data contracts as just a place to stick data with no other functionality. To confirm, you can look in the reference.cs class that got generated in the client when you added the service reference.

I'd suggest re-writing the code so that you explicitly set each of the values in your data contract rather than relying on the constructor.

You can also write a hand coded proxy that has whatever behavior you want and then share that file with the client. That would work, but then you'll be more tightly coupling your client to your service.

0
votes

Turns out, my translation layer wasn't updated to convert between the DTOs! Whooooops!