WCF问题传递复杂类型

时间:2008-09-15 22:51:05

标签: .net wcf wsdl

我有一个服务契约,它定义了一个参数类型为System.Object的方法(WSDL中的xs:anyType)。我希望能够在此参数中传递简单类型和复杂类型。简单类型工作正常,但是当我尝试传递我的WSDL中定义的复杂类型时,我收到此错误:

元素“http://tempuri.org/:value”包含“http://schemas.datacontract.org/2004/07/MyNamespace:MyClass”数据合约的数据。反序列化器不知道映射到此合同的任何类型。将与“MyClass”对应的类型添加到已知类型列表中 - 例如,通过使用KnownTypeAttribute属性或将其添加到传递给DataContractSerializer的已知类型列表中。

将其添加为已知类型无济于事,因为它已经在我的WSDL中。如何通过“xs:anyType”参数传递复杂类型的对象?

更多信息:

我相信这在使用NetDataContract时有效,但由于我的客户端是Silverlight,我无法使用它。

我已经看到了对显式扩展xs:anyType的复杂类型的引用,但我不知道如何让WCF生成一个能够做到这一点的WSDL,而且我不知道它是否会有所帮助。

由于

6 个答案:

答案 0 :(得分:2)

NetDataContract有效,因为NetDataContractSerializer包含类型信息。

KnownType属性指示DataContractSerializer如何反序列化消息。作为特定于实现,这是由公共合同定义的信息,而不属于WSDL。

您永远无法传递任何旧数据类型,因为反序列化器需要识别适当的类型并创建实例。

您可以在运行时派生已知类型,而不是在DataContract中对它们进行硬编码。看看here样本。

答案 1 :(得分:1)

我希望这会有所帮助。我看到我的一位同事使用此代码发送复杂的数据类型,对我来说这非常简单。这与basicHttpBinding一起使用,它与MOSS BDC以及使用基本绑定的其他应用程序非常兼容。

  1. 基于通用类
  2. 创建数据协定
  3. 需要发送信息时使用数据合同

    [DataContract(Namespace =“http://Service.DataContracts”,Name =“ServiceDataContractBase”)] 公共类ServiceDataContract {

    public ServiceDataContract() { }
    
    public ServiceDataContract(TValueType Value)
    {
        this.m_objValue = Value;
    }
    
    private TValueType m_objValue;
    
    [DataMember(IsRequired = true, Name = "Value", Order = 1)]
    public TValueType Value
    {
        get { return m_objValue; }
        set { m_objValue = value; }
    }
    

    }

  4. 在返回复杂数据类型的WCF函数中需要使用此数据协定。例如:

    public ServiceDataContract<string[]> GetStrings()
    {
        string[] temp = new string[10];
        return new ServiceDataContract<string[]>(temp);
    }
    

    更新:ServiceDataContract是泛型类正在使用TValueType。由于HTML的呈现有问题,它没有出现。

答案 2 :(得分:1)

我已使用ServiceKnownType属性解决了这个问题。我只是在服务合同中添加我的复杂类型作为服务已知类型,错误就消失了。我不确定为什么上次我尝试时这不起作用。

它似乎没有以任何方式影响WSDL,所以我怀疑序列化流必须有一些区别,通知反序列化器可以使用我的类型反序列化对象。

答案 3 :(得分:0)

尝试使用数据合同代理来映射不支持的对象,这些对象是特定于网络的或不可互操作的类型。见MSDN

答案 4 :(得分:0)

我尝试添加ServiceKnownType属性,指定我尝试传递的类型,但我仍然得到相同的错误。我也尝试将KnownType属性添加到我的数据契约中(看起来很傻,因为它与数据合同的类型相同)。我想如果在编译时添加它们会在运行时添加它们无济于事。

如果我正在扩展另一个复杂类型,在我看来我想要将KnownType属性添加到该基类型。但由于我的基类型是Object,我认为没有办法做到这一点。

至于代理人,在我看来,这些用于没有定义合同的包装类型。然而,在我的情况下,我确实已经定义了合同。

答案 5 :(得分:0)

现在我通过创建一个可以包装另一个数据协定类型或简单类型的新数据协定类型来解决这个问题。现在我传递这个包装类,而不是传递类型Object。这项工作正常,但我仍然想知道是否有原始问题的解决方案。