编写 C# 客户端以使用返回对象数组的 Java Web 服务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/64833/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 10:30:14  来源:igfitidea点击:

Writing C# client to consume a Java web service that returns array of objects

提问by David Chappelle

I am writing a C# client that calls a web service written in Java (by another person). I have added a web reference to my client and I'm able to call methods in the web service ok.

我正在编写一个 C# 客户端,它调用用 Java 编写的 Web 服务(由另一个人)。我已经向我的客户端添加了一个 web 引用,我可以调用 web 服务中的方法。

The service was changed to return an array of objects, and the client does not properly parse the returned SOAP message.

服务已更改为返回对象数组,并且客户端未正确解析返回的 SOAP 消息。

MyResponse[] MyFunc(string p)

class MyResponse
{
    long id;
    string reason;
}

When my generated C# proxy calls the web service (using SoapHttpClientProtocol.Invoke), I am expecting a MyResponse[] array with length of 1, ie a single element. What I am getting after the Invoke call is an element with id=0 and reason=null, regardless of what the service actually returns. Using a packet sniffer, I can see that the service is returning what appears to be a legitimate soap message with id and reason set to non-null values.

当我生成的 C# 代理调用 Web 服务(使用 SoapHttpClientProtocol.Invoke)时,我期待一个长度为 1 的 MyResponse[] 数组,即单个元素。Invoke 调用后我得到的是一个 id=0 和 reason=null 的元素,不管服务实际返回什么。使用数据包嗅探器,我可以看到该服务正在返回一条看似合法的肥皂消息,其中 id 和 reason 设置为非空值。

Is there some trick to getting a C# client to call a Java web service that returns someobject[] ? I will work on getting a sanitized demo if necessary.

让 C# 客户端调用返回 someobject[] 的 Java Web 服务有什么技巧吗?如有必要,我将努力获得经过消毒的演示。

Edit: This is a web reference via "Add Web Reference...". VS 2005, .NET 3.0.

编辑:这是通过“添加 Web 引用...”的 Web 引用。VS 2005,.NET 3.0。

采纳答案by Xian

It has been a while, but I seem to remember having trouble with the slight differences in how default namespaces were handled between .Net and Java web services.

已经有一段时间了,但我似乎记得在 .Net 和 Java Web 服务之间处理默认名称空间的方式上存在细微差别时遇到了麻烦。

Double check the generated c# proxy class and any namespaces declared within (especially the defaults xmlns=""), against what the Java service is expecting. There will be probably be very subtle differences which you will have to recreate.

仔细检查生成的 c# 代理类和其中声明的任何命名空间(尤其是默认值 xmlns=""),是否符合 Java 服务的预期。可能会有非常细微的差异,您必须重新创建。

If this is the case then you will to provide more namespace declarations in the c# attributes.

如果是这种情况,那么您将在 c# 属性中提供更多命名空间声明。

回答by Xian

From your question, it looks like you had the client working at one point, and then the service was changed to return an array. Make sure you re-generate the proxy so the returned SOAP message is deserialized on the client. It wasn't clear you had done this - just making sure.

从您的问题来看,您似乎让客户端在某一时刻工作,然后将服务更改为返回一个数组。确保重新生成代理,以便在客户端反序列化返回的 SOAP 消息。不清楚你是否这样做了——只是确定一下。

回答by David Chappelle

Thanks to Xian, I have a solution.

感谢Xian,我有一个解决方案。

The wsdl for the service included a line

该服务的 wsdl 包括一行

<import namespace="http://mynamespace.company.com"/>

The soap that the client sent to the server had the following attribute on all data elements:

客户端发送到服务器的肥皂在所有数据元素上都具有以下属性:

xmlns="http://mynamespace.company.com"

But the xml payload of the response (from the service back to the client) did nothave this namespace included. By tinkering with the HTTP response (which I obtained with WireShark), I observed that the .NET proxy class correctly picked up the MyResponse values if I forced the xmlns attribute on every returned data element.

但响应(从服务返回给客户端)的XML负载并没有这个命名空间包含在内。通过修改 HTTP 响应(我通过WireShark获得),我观察到如果我在每个返回的数据元素上强制使用 xmlns 属性,.NET 代理类会正确地获取 MyResponse 值。

Short of changing the service, which I don't control, the workaround is to edit the VS generated proxy class (eg Reference.cs) and look for lines like this:

除了更改我无法控制的服务之外,解决方法是编辑 VS 生成的代理类(例如 Reference.cs)并查找如下行:

[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://mynamespace.company.com")]
public partial class MyResponse {

and comment out the XmlType attribute line. This will tell the CLR to look for response elements in the default namespace rather than the one specied in the wsdl. You have to redo this whenever you update the reference, but at least it works.

并注释掉 XmlType 属性行。这将告诉 CLR 在默认命名空间中查找响应元素,而不是在 wsdl 中指定的元素。每当您更新参考时,您都必须重做此操作,但至少它有效。