WCF 客户端调用 Java Web 服务:XmlSerializer 找不到派生类型
这看起来像是一个基本的 Web 服务问题。然而,根据我所做的一些研究,优雅的解决方案是难以捉摸的。我想我在这里遗漏了一些东西,
我正在使用 WCF 客户端连接到我无法控制的外部 Web 服务。外部WS是基于java的。提供了一堆程序集来调用 Web 服务中的方法。这些程序集具有基类和派生类。 Web 服务方法可以将基类作为参数,而从 WCF 客户端我实例化一个派生类并将其传递给该方法。
为了模拟这一场景,我创建了一个带有一个 ClassLibrary 的小项目,其中包含一个 BaseClass 和一个带有一种方法的 DerivedClass。
然后我创建一个 asmx Web 服务并在其中添加一个 HelloWorld 方法。我添加了对 ClassLibrary 的引用。此方法采用 BaseClass 类型参数。
然后,我创建对 ASMX Web 服务的服务引用。在代理类中,我将 XmlSerializerFormatAttribute 添加到该方法(如果该方法尚不存在)。
从 WCF 客户端,我调用 ASMX Web 方法
BaseClass bc = new Derived();
ServiceReference1.TestService ts = new WCFTest.ServiceReference1.TestService();
lbl1.Text = (c1.HelloWorld(bc));
调用失败并出现错误 不是预期的 ClassLib.Derived 类型。使用 XmlInclude 或 SoapInclude 属性来指定静态未知的类型。
调用此 Web 服务方法的唯一方法是将 XmlInclude 属性添加到 ClassLibrary 中的 BaseClass。 在我的场景中,该库是外部供应商提供的 dll。我无法向其类添加属性。我查看了 DataContractSerializer 和 KnownTypes 和 XmlSerializer 构造函数。然而这些解决方案似乎不适用于我的场景。
如何使 XMLSerializer 查看我在 WCF 客户端中引用的程序集中的派生类?有优雅的解决方案吗?
谢谢, 下摆
This seems like a fundamental Web Services problem. However an elegant solution is elusive based on some research I have been able to do. I guess I am missing something here
I am using a WCF client to connect to a External web service of which I have no control. The external WS is java based. There are a bunch of assemblies which are provided to call the methods in web service. These assemblies have base classes and derived classes. The web service methods can take Base class as param whereas from the WCF Client I instantiate a Derived class and pass it to the method.
To simulate this scenario, I created a small project with one ClassLibrary which has a BaseClass and a DerivedClass with one method.
Then I create an asmx web service and add a HelloWorld method inside it. I add a reference to the ClassLibrary. This method takes a BaseClass type param.
Then I create a Service Reference to the ASMX web service. In the proxy class, I add a XmlSerializerFormatAttribute to the method if it is already not there.
From the WCF client, I call the ASMX web method
BaseClass bc = new Derived();
ServiceReference1.TestService ts = new WCFTest.ServiceReference1.TestService();
lbl1.Text = (c1.HelloWorld(bc));
The call fails with error
The type ClassLib.Derived was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
The only way I could call this web service method was by adding XmlInclude attribute to the BaseClass in the ClassLibrary.
In my scenario, this library is a dll provided by an external vendor. I cannot add attributes to its classes. I have looked a DataContractSerializer and KnownTypes and XmlSerializer ctor. However those solutions do not seem to be applicable in my scenario.
How can I make XMLSerializer see the Derived classes in the assemblies I have referencing in the WCF Client? Is there an elegant solution?
Thanks,
Hem
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为 XmlSerializerOperationBehavior 包含您自己的类型映射可能会起作用,但我还没有尝试过此操作(请参阅 GetXmlMappings)。
http://msdn.microsoft.com/en-us /library/system.servicemodel.description.xmlserializeroperationbehavior.aspx
或者,通过以下方式强制使用 DataContractSerializer:如果您指定自己的已知类型,DataContractSerializerOperationBehavior(与现在使用的 XmlSerializerOperationBehavior 相对)也可能有效
http://msdn.microsoft.com/en-us/library/ms576751%28v=vs.85%29.aspx
最后,作为最后的手段,您可以强制使用使用 DataContractSerializerOperationBehavior 的 DataContractSerializer,然后指定您自己的 DataContractSurrogate 以强制使用 XmlSerializer,您可以在其中将自定义类型传递给其构造函数(这规避了 XmlInclude 属性的要求)。
http://msdn.microsoft.com/en-us/library/ms751540.aspx
希望有帮助。
Including your own type mapping for an XmlSerializerOperationBehavior may just work, but I haven't tried this (see GetXmlMappings).
http://msdn.microsoft.com/en-us/library/system.servicemodel.description.xmlserializeroperationbehavior.aspx
Alternatively, forcing use of the DataContractSerializer via a DataContractSerializerOperationBehavior (as opposed to the XmlSerializerOperationBehavior it's using now) may work too, if you specify your own known types
http://msdn.microsoft.com/en-us/library/ms576751%28v=vs.85%29.aspx
Finally, as a last resort, you can force use of the DataContractSerializer using the DataContractSerializerOperationBehavior, then specify your own DataContractSurrogate to force use of the XmlSerializer where you can pass custom types to its constructor (which circumvents the requirement for the XmlInclude attribute).
http://msdn.microsoft.com/en-us/library/ms751540.aspx
Hope that helps.