2

我需要使用标准 wsdl 调用 web 服务操作,但客户端和服务器中的数据对象必须不同。

使用通用库中数据对象的接口,在客户端和服务器中为其创建代理类。

然后,我使用接口声明操作合同,但 WCF 不识别它。

我还尝试过使用 DataContractSerializerBehavior 并设置 knownTypes,但还没有成功。

有人可以帮我吗?我附上了一个包含更多细节的完整解决方案。

public interface Thing
{
   Guid Id {get;set;}
   String name {get;set;}
   Thing anotherThing {get;set;}
}

[DataContract]
public class ThingAtServer: BsonDocument, Thing // MongoDB persistence
{ 
   [DataMember]
   Guid Id {get;set;}
   //... 
}

[DataContract]
public class ThingAtClient: Thing, INotifyPropertyChanged // WPF bindings
{ 
   [DataMember]
   Guid Id {get;set;}
   //... 
}

[ServiceContract]
public interface MyService
{
  [OperationContract]
  Thing doSomething(Thing input);
}

单击此处在 GitHub 上查看带有 TestCases的示例项目

4

2 回答 2

2

我用合同创建了 WCF 服务:

[OperationContract]
CompositeTypeServer GetDataUsingDataContract( CompositeTypeServer composite );

我的CompositeTypeServer样子是这样的:

[DataContract( Namespace = "http://enes.com/" )]
public class CompositeTypeServer
{
    [DataMember]
    public bool BoolValue { get; set; }

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

然后我创建了类型为的客户端项目CompositeTypeClient

[DataContract( Namespace = "http://enes.com/" )]
public class CompositeTypeClient
{
    [DataMember]
    public bool BoolValue { get; set; }

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

然后我添加了对我的服务的引用并选择重用类型。一切都像魅力一样。我能够CompositeTypeClient在客户端使用。

所以诀窍是为 DataContract 指定命名空间,以便它们在客户端和服务上都匹配。

[DataContract( Namespace = "http://enes.com/" )]

PS。我可以根据要求提供完整的 VS 解决方案。

于 2013-04-05T22:35:58.033 回答
0

根据ServiceKnownTypeAttributeMSDN 文档),我根据情况更改了预期的类型。主要思想在类中实现,负责根据情况XHelper返回正确的:Type[]

public static class XHelper
{

    public static Boolean? IsClient = null;
    public static Type[] ClientTypes;
    public static Type[] ServerTypes;

    public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider pProvider)
    {
        if (!IsClient.HasValue)
            throw new Exception("Invalid value");
        if (IsClient.Value)
            return ClientTypes;
        return ServerTypes;
    }
}

您必须在具有to know类ServiceKnownType的接口中包含标记。ServiceContractXHelper

[ServiceContract(Namespace = MyProxyProvider.MyNamespace)]
[ServiceKnownType("GetKnownTypes", typeof(XHelper))]
public interface MyService
{
    [OperationContract]
    Thing2 CopyThing(Thing1 input);
}

在测试单元开始时,它被告知Type[]每种情况的权利:

    [AssemblyInitialize]
    public static void TestInitialize(TestContext pContext)
    {
        XHelper.ClientTypes = new Type[] { typeof(Thing1ProxyAtClient), typeof(Thing2ProxyAtClient), typeof(Thing2ProxyAtClient) };
        XHelper.ServerTypes = new Type[] { typeof(Thing1ProxyAtServer), typeof(Thing2ProxyAtServer), typeof(ThingNProxyAtServer) };
    }

单击此处查看 GitHub 上带有 TestCases的最终代码示例项目

于 2013-04-06T15:55:35.157 回答