简体   繁体   English

WCF Guid DataMember未正确序列化

[英]WCF Guid DataMember not Serialized properly

I have a WCF service that passes back and forth the following DataContracts: 我有一个WCF服务,该服务来回传递以下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: 然后使用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. 我在VS调试器中的Guid上放了一块手表。 When the service is called from a client web application, the generated Guid is a valid Guid of seemingly random hex characters. 当从客户端Web应用程序调用该服务时,生成的Guid是看似随机的十六进制字符的有效Guid。 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! 但是,当数据被序列化,遍历整个网络并从另一端出来(在我的存储库中)时,Guid就是全零!

I've double, triple checked that the Guid is indeed marked with the [DataMember] attribute. 我已经两次,三次检查了Guid确实标记有[DataMember]属性。 I'm wondering if the extra layer of DataContract (how a FooDataContract is wrapped with the RequestWrapper data contract) is causing a serialization issue? 我想知道是否DataContract的额外层(如何用RequestWrapper数据协定包装FooDataContract)导致序列化问题?

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. 我认为您的问题在于,您在DataContract类中创建的构造函数没有传递给客户端的代理。 WSDL won't know anything about this. WSDL对此一无所知。 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. 为了确认,您可以查看添加服务引用时在客户端中生成的reference.cs类。

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. 那会起作用,但是那样您会更紧密地将客户与服务耦合起来。

Turns out, my translation layer wasn't updated to convert between the DTOs! 原来,我的翻译层没有更新,无法在DTO之间转换! Whooooops! 哎呀!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM