.NET调用Web服务并返回null

时间:2011-11-29 14:42:02

标签: .net xml web-services soap

我有一个web服务,我已将它作为Web引用添加到我的.NET项目中。其中一个Web方法返回一个嵌套数组(NameValuePairDTOArray [NameValuePairDTO [])。我只能在.NET代码中获取null对象,但是当我通过SoapUI测试时它确实返回了数据。

我在这里粘贴了一些wsdl文件。

这是方法定义。

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://services.mymachine.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IneteractionService" targetNamespace="http://services.mymachine.com/">
    <operation name="getValue" parameterOrder="parameters">
        <input message="tns:MyServices_getValues"/>
        <output message="tns:MyServices_getValuesResponse"/>
        <fault message="tns:ServiceException" name="ServiceException"/>
    </operation>

    <xs:schema xmlns:ns1="http://ods.mymachine.com/v1_0_0" xmlns:tns="http://services.mymachine.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://services.mymachine.com/" version="1.0">
        <xs:import namespace="http://ods.mymachine.com/v1_0_0"/>
        <xs:element name="ServiceException" type="tns:ServiceException"/>
        <xs:element name="getValue" type="tns:getValue"/>
        <xs:element name="getValuesResponse" type="tns:getValuesResponse"/>
        <xs:complexType name="getValue">
            <xs:sequence>
            <xs:element minOccurs="0" name="firstName" type="xs:string"/>
            <xs:element minOccurs="0" name="lastName" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
        <xs:complexType name="getValuesResponse">
            <xs:sequence>
            <xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="ns1:NameValuePairDTOArray"/>
            </xs:sequence>
        </xs:complexType>
    </xs:schema>
</definitions>

这是响应数据定义。

<xs:schema xmlns:ns1="http://common.mymanchine.com/v1_0_0" xmlns:tns="http://ods.mymachine.com/v1_0_0" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://ods.mymachine.com/v1_0_0" version="1.0">
    <xs:import namespace="http://common.mymanchine.com/v1_0_0"/>
    <xs:complexType final="#all" name="NameValuePairDTOArray">
        <xs:sequence>
        <xs:element maxOccurs="unbounded" minOccurs="0" name="item" nillable="true" type="tns:NameValuePairDTO"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="NameValuePairDTO">
        <xs:complexContent>
            <xs:extension base="ns1:DataTransferObject">
                <xs:sequence/>
                <xs:attribute name="name" type="xs:string"/>
                <xs:attribute name="value" type="xs:string"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
</xs:schema

.NET生成的代理类如:

[WebServiceBinding(Name = "InteractionServicesBinding", Namespace = "http://services.mymachine.com/")]
[XmlInclude(typeof(DataTransferObject))]
[DebuggerStepThrough]
[GeneratedCode("System.Web.Services", "4.0.30319.1")]
[DesignerCategory("code")]
public class InteractionServicesServiceWse : WebServicesClientProtocol
{
    public InteractionServicesServiceWse();

    [SoapDocumentMethod("", RequestNamespace = "http://services.mymachine.com/", 
     ResponseNamespace = "http://services.services.mymachine.com/", Use = SoapBindingUse.Literal, ParameterStyle = SoapParameterStyle.Wrapped)]
    public NameValuePairDTOArray[] getValue(string firstName, string lastName);
}

[Serializable]
[XmlType(Namespace = "http://ods.mymachine.com/v1_0_0")]
[GeneratedCode("System.Xml", "4.0.30319.233")]
[DebuggerStepThrough]
[DesignerCategory("code")]
public class NameValuePairDTOArray
{
    public NameValuePairDTOArray();

    [XmlElement("item", IsNullable = true)]
    public NameValuePairDTO[] item { get; set; }
}

[Serializable]
[DesignerCategory("code")]
[XmlType(Namespace = "http://ods.mymachine.com/v1_0_0")]
[GeneratedCode("System.Xml", "4.0.30319.233")]
[DebuggerStepThrough]
public class NameValuePairDTO : DataTransferObject
{
    public NameValuePairDTO();

    [XmlAttribute]
    public string name { get; set; }
    [XmlAttribute]
    public string value { get; set; }
}

现在,如果我调用getValue(“John”,“Peter”),它将在.NET中返回如下。

enter image description here

但soapUI返回的内容如下:

<env:Body>
  <ns2:getValueResponse xmlns:ns2="http://services.mymachine.com/">
     <return>
        <item value="123" name="BONUS_ID"/>
        <item value="456" name="POPUP_OBJECT_ID"/>
     </return>
     <return>
        <item value="123" name="BONUS_ID"/>
        <item value="567" name="POPUP_OBJECT_ID"/>
     </return>
  </ns2:getValueResponse>
</env:Body>

似乎.NET无法检测到NameValuePairDTO / item是一个数组。

怎么了?

2 个答案:

答案 0 :(得分:2)

嗯,问题是服务器端出了问题。

定义了NameValuePairDTOArray和NameValuePairDTO的模式。{/ p>

但是看看响应xml,

<env:Body>
  <ns2:getValueResponse xmlns:ns2="http://services.mymachine.com/">
     <return>
        <item value="123" name="BONUS_ID"/>
        <item value="456" name="POPUP_OBJECT_ID"/>
     </return>
     <return>
        <item value="123" name="BONUS_ID"/>
        <item value="567" name="POPUP_OBJECT_ID"/>
     </return>
  </ns2:getValueResponse>

return(NameValuePairDTOArray)和item(NameValuePairDTO)是不合格的。生成的代理类假定它们是合格的,因为定义了模式,但这导致无法解析xml。

快速修复将手动将不受限制的属性添加到NameValuePairDTOArray类中的NameValuePairDTO属性。将来,服务端应解决此问题。

答案 1 :(得分:1)

生成的代码中的NameValuePairDTOArray随命名空间一起显示&#34; http://ods.mymachine.com/v1_0_0"但是这个命名空间不在xml输出中(所以.net不知道标签&#34; return&#34;指的是NameValuePairDTOArray)。

也许你从服务器的代码中删除了XmlTypeAttribute。

所以你应该:在客户端刷新你的web引用,或者在服务器端添加回XmlTypeAttribute。