WCF问题传递复杂类型
我有一个服务合同,该合同定义了一个参数类型为System.Object(WSDL中的xs:anyType)的方法。我希望能够在此参数中传递简单类型以及复杂类型。简单类型可以很好地工作,但是当我尝试传递在WSDL中定义的复杂类型时,出现此错误:
元素" http://tempuri.org/:value"包含" http://schemas.datacontract.org/2004/07/MyNamespace:MyClass"数据协定的数据。解串器不知道任何映射到该合同的类型。例如,通过使用KnownTypeAttribute属性或者将其添加到传递给DataContractSerializer的已知类型列表中,将与" MyClass"相对应的类型添加到已知类型列表中。
将其添加为已知类型无济于事,因为它已经在我的WSDL中。如何通过" xs:anyType"参数传递复杂类型的对象?
更多信息:
我相信这在使用NetDataContract时有效,但是我不能使用它,因为我的客户是Silverlight。
我已经看到了对显式扩展xs:anyType的复杂类型的引用,但是我不知道如何使WCF生成执行此操作的WSDL,也不知道它是否会有所帮助。
谢谢
解决方案
回答
NetDataContract之所以有效,是因为NetDataContractSerializer包含类型信息。
KnownType属性指示DataContractSerializer如何反序列化消息。由于是特定于实现的,因此这是公共合同定义的重要信息,并不属于WSDL。
我们将永远无法传递任何旧的数据类型,因为解串器需要标识适当的类型并创建实例。
我们也许能够在运行时派生已知类型,而不必在DataContract中对其进行硬编码。在这里查看示例。
回答
尝试使用数据合同代理来映射点网络特定的或者不可互操作类型的不受支持的对象。参见MSDN
回答
我尝试添加ServiceKnownType属性,指定要尝试传递的类型,但是仍然遇到相同的错误。我还尝试过将KnownType属性添加到我的数据协定中(这看起来很愚蠢,因为它与数据协定的类型相同)。我猜想,如果在编译时添加它们没有帮助,则在运行时添加它们将无济于事。
如果要扩展其他复杂类型,在我看来,我想将KnownType属性添加到该基本类型。但是由于我的基本类型是Object,所以看不到任何实现此目的的方法。
至于代理人,在我看来,这些代理人用于包装没有定义合同的类型。但就我而言,我确实已定义了合同。
回答
我希望这会有所帮助。我看到我的一位同事使用此代码发送复杂的数据类型,对我来说这很简单。这与basicHttpBinding一起使用,并且与MOSS BDC以及其他使用基本绑定的应用程序一起很好地工作。
- 根据通用类创建数据合同
- 在需要发送信息时使用数据协定[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; } }
}
在返回复杂数据类型的WCF函数中需要的地方使用此数据协定。例如:
public ServiceDataContract<string[]> GetStrings() { string[] temp = new string[10]; return new ServiceDataContract<string[]>(temp); }
更新:ServiceDataContract是使用TValueType的通用类。由于HTML呈现出现问题,因此未显示。
回答
现在,我已经通过创建一个新的数据协定类型来解决此问题,该数据协定类型可以包装另一个数据协定类型或者简单类型。现在,我传递此包装器类,而不是传递类型Object。可以,但是我仍然想知道是否有解决原始问题的方法。
回答
我已经通过使用ServiceKnownType属性解决了此问题。我只需将我的复杂类型添加为服务合同中的服务已知类型,错误就会消失。我不确定为什么上次尝试时这种方法不起作用。
它似乎没有以任何方式影响WSDL,所以我怀疑序列化的流必须具有一定的区别,以告知反序列化器可以使用我的类型对对象进行反序列化。