简体   繁体   English

WCF DataContract等价混淆

[英]WCF DataContract Equivalence confusion

I have a server side DataContract like this: 我有这样的服务器端DataContract

[DataContract(Name = "CommonType", Namespace = "http://mycompany.com/2014/09/DataService")]
public class CompositeType
{
    bool boolValue = true;
    string stringValue = "Hello ";

    [DataMember(Name="Property1")]
    public bool BoolValue
    {
        get { return boolValue; }
        set { boolValue = value; }
    }

   [DataMember(Name = "Property2")]
    public string StringValue
    {
        get { return stringValue; }
        set { stringValue = value; }
    }
}

The server side class name is CompositeType with a specified DataContract name and namespace. 服务器端类名称是CompositeType ,具有指定的DataContract名称和名称空间。

The client side class looks like this: 客户端类如下所示:

[DataContract(Name = "CommonType", Namespace = "http://mycompany.com/2014/09/DataService")]
public class ClientType
{
    bool boolValue;
    string stringValue;

    [DataMember(Name = "Property1")]
    public bool ClientBoolValue
    {
        get { return boolValue; }
        set { boolValue = value; }
    }

    [DataMember(Name = "Property2")]
    public string ClientStringValue
    {
        get { return stringValue; }
        set { stringValue = value; }
    }
}

The client side class is a different type but same DataContract name and namespace. 客户端类是不同的类型,但具有相同的DataContract名称和名称空间。

The ServiceContract looks like this: ServiceContract看起来像这样:

[ServiceContract]
public interface IService1
{
    [OperationContract]
    CompositeType GetDataUsingDataContract(CompositeType composite);

}

The implementation is this: 实现是这样的:

public class Service1 : AES.Services.Data.IService1
{
    public AES.Services.Data.CompositeType GetDataUsingDataContract(AES.Services.Data.CompositeType composite)
    {
        if (composite == null)
        {
            throw new ArgumentNullException("composite");
        }
        if (composite.BoolValue)
        {
            composite.StringValue += "Suffix";
        }
        return composite;
    }
}

How do I leverage my client side type to be used for the datacontract type? 如何利用我的客户端类型用作数据合同类型? The client side generates a proxy to the service and the type generated is new class. 客户端生成服务的代理,并且生成的类型是新类。 Shouldn't I be able to use the client side type that has the DataContract name that matches the server side DataContract? 我是否应该能够使用具有与服务器端DataContract匹配的DataContract名称的客户端类型?

I'm expecting to be able to execute this code on the client, no? 我希望能够在客户端上执行此代码,不是吗?

        Service.Service1Client client = new Service.Service1Client();

        ClientType ct = new ClientType();
        client.GetDataUsingDataContract(ct);

But the above code fails because the argument I'm passing is not the proxy class that was generated via the service reference generation. 但是上面的代码失败了,因为我传递的参数不是通过服务引用生成而生成的代理类。 How am I suppose to use my client side version of the data contract???? 我应该如何使用我的客户端数据合同版本?

UPDATE UPDATE

The solution I have found to work was to use the channel factory, and create my own client side ServiceContract and DataContract, at first I didn't like it but I realized that is exactly what the ServiceReference is doing anyway. 我发现可以使用的解决方案是使用通道工厂,并创建自己的客户端ServiceContract和DataContract,起初我不喜欢它,但是我意识到这正是ServiceReference所做的。 I put a common name and namespace on the ServiceContractAttribute and the DataContractAttribute on both the client and server. 我在客户端和服务器上的ServiceContractAttribute和DataContractAttribute上都添加了通用名称和名称空间。 Now I can have independent development/evolution of my classes. 现在,我可以对自己的班级进行独立的开发/发展了。

This link supports this approach as well: http://www.codeproject.com/Articles/55690/WCF-Loose-coupling-of-WCF-Service-and-Data-Contrac 此链接也支持此方法: http : //www.codeproject.com/Articles/55690/WCF-Loose-coupling-of-WCF-Service-and-Data-Contrac

The key to using client-side entities with WCF is to: a) Place them in a separate assembly/project (if they are not already there). 将客户端实体与WCF一起使用的关键是:a)将它们放在单独的程序集/项目中(如果尚不存在)。 b) Remove the service reference if you already added it. b)删除服务参考(如果已添加)。 c) Add a project reference from the client project to the entities project. c)将项目参考从客户项目添加到实体项目。 d) Re-add the service reference d)重新添加服务参考

SvcUtil, which is used by VS to add service references, will use the entities in the referenced project instead of generating them. VS用于添加服务引用的SvcUtil将使用引用项目中的实体,而不是生成它们。

There is one caveat to this. 有一个警告。 Adding a service reference may not work if the entities in the client and server are in different assemblies. 如果客户端和服务器中的实体位于不同的程序集中,则无法添加服务引用。 I have to dig further into why this is sometimes the case. 我必须进一步研究为什么有时会出现这种情况。 But if adding a service reference does not work, then all you have to do is use a ChannelFactory instead. 但是,如果添加服务引用不起作用,那么您要做的就是使用ChannelFactory。

Cheers, Tony 干杯,托尼

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

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