2014-09-22 99 views
1

我想用.Net来使用iseries web服务。我已经成功地与iSeries上的其他Web服务进行通信,但在这个特定的服务器上,我遇到了一个很奇怪的问题。.net消费iSeries网络服务

以下是iSeries Web服务的wsdl。

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:tns="http://example.com/ZCntInfFr/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ZCntInfFr" 
targetNamespace="http://example.com/ZCntInfFr/"> 
<wsdl:types> 
    <xsd:schema targetNamespace="http://example.com/ZCntInfFr/"> 
     <xsd:element name="GetContactInfoOperation"> 
      <xsd:complexType> 
       <xsd:sequence> 
        <xsd:element name="ShipToAcct" minOccurs="1" 
         maxOccurs="1"> 
         <xsd:simpleType> 
          <xsd:restriction base="xsd:string"> 
           <xsd:length value="6"></xsd:length> 
          </xsd:restriction> 
         </xsd:simpleType> 
        </xsd:element> 
       </xsd:sequence> 
      </xsd:complexType> 
     </xsd:element> 
     <xsd:element name="GetContactInfoOperationResponse"> 
      <xsd:complexType> 
       <xsd:sequence> 
        <xsd:element name="Contacts" 
         type="tns:ContactsType" minOccurs="1" maxOccurs="1"> 
        </xsd:element> 
       </xsd:sequence> 
      </xsd:complexType> 
     </xsd:element> 
     <xsd:complexType name="ContactDataType"> 
      <xsd:sequence maxOccurs="unbounded" minOccurs="0"> 
       <xsd:element name="ContactType" minOccurs="0" 
        maxOccurs="1"> 
        <xsd:simpleType> 
         <xsd:restriction base="xsd:string"> 
          <xsd:minLength value="0"></xsd:minLength> 
          <xsd:maxLength value="5"></xsd:maxLength> 
         </xsd:restriction> 
        </xsd:simpleType> 
       </xsd:element> 
       <xsd:element name="ContactTypeDesc" minOccurs="0" 
        maxOccurs="1"> 
        <xsd:simpleType> 
         <xsd:restriction base="xsd:string"> 
          <xsd:minLength value="0"></xsd:minLength> 
          <xsd:maxLength value="50"></xsd:maxLength> 
         </xsd:restriction> 
        </xsd:simpleType> 
       </xsd:element> 
       <xsd:element name="ContactName" minOccurs="0" 
        maxOccurs="1"> 
        <xsd:simpleType> 
         <xsd:restriction base="xsd:string"> 
          <xsd:minLength value="0"></xsd:minLength> 
          <xsd:maxLength value="25"></xsd:maxLength> 
         </xsd:restriction> 
        </xsd:simpleType> 
       </xsd:element> 
       <xsd:element name="ContactTitle" minOccurs="0" 
        maxOccurs="1"> 
        <xsd:simpleType> 
         <xsd:restriction base="xsd:string"> 
          <xsd:minLength value="0"></xsd:minLength> 
          <xsd:maxLength value="20"></xsd:maxLength> 
         </xsd:restriction> 
        </xsd:simpleType> 
       </xsd:element> 
       <xsd:element name="ContactEmail" minOccurs="0" 
        maxOccurs="1"> 
        <xsd:simpleType> 
         <xsd:restriction base="xsd:string"> 
          <xsd:minLength value="0"></xsd:minLength> 
          <xsd:maxLength value="128"></xsd:maxLength> 
         </xsd:restriction> 
        </xsd:simpleType> 
       </xsd:element> 
       <xsd:element name="ContactPhone" minOccurs="0" 
        maxOccurs="1"> 
        <xsd:simpleType> 
         <xsd:restriction base="xsd:string"> 
          <xsd:minLength value="0"></xsd:minLength> 
          <xsd:maxLength value="15"></xsd:maxLength> 
         </xsd:restriction> 
        </xsd:simpleType> 
       </xsd:element> 
       <xsd:element name="ContactExtension" minOccurs="0" 
        maxOccurs="1"> 
        <xsd:simpleType> 
         <xsd:restriction base="xsd:string"> 
          <xsd:minLength value="0"></xsd:minLength> 
          <xsd:maxLength value="5"></xsd:maxLength> 
         </xsd:restriction> 
        </xsd:simpleType> 
       </xsd:element> 
       <xsd:element name="ContactFax" minOccurs="0" maxOccurs="1"> 
        <xsd:simpleType> 
         <xsd:restriction base="xsd:string"> 
          <xsd:minLength value="0"></xsd:minLength> 
          <xsd:maxLength value="15"></xsd:maxLength> 
         </xsd:restriction> 
        </xsd:simpleType> 
       </xsd:element> 
    </xsd:sequence> 
     </xsd:complexType> 
     <xsd:complexType name="ContactsType"> 
      <xsd:sequence maxOccurs="unbounded" minOccurs="0"> 
       <xsd:element name="ContactData" type="tns:ContactDataType" maxOccurs="1" minOccurs="0"></xsd:element> 
      </xsd:sequence> 
     </xsd:complexType> 
    </xsd:schema> 
</wsdl:types> 
<wsdl:message name="GetContactInfoOperationRequest"> 
    <wsdl:part name="parameters" element="tns:GetContactInfoOperation"></wsdl:part> 
</wsdl:message> 
<wsdl:message name="GetContactInfoOperationResponse"> 
    <wsdl:part name="parameters" element="tns:GetContactInfoOperationResponse"></wsdl:part> 
</wsdl:message> 
<wsdl:portType name="ZCntInfFr"> 
    <wsdl:operation name="GetContactInfoOperation"> 
     <wsdl:input message="tns:GetContactInfoOperationRequest"></wsdl:input> 
     <wsdl:output message="tns:GetContactInfoOperationResponse"></wsdl:output> 
    </wsdl:operation> 
</wsdl:portType> 
<wsdl:binding name="ZCntInfFrSOAP" type="tns:ZCntInfFr"> 
    <soap:binding style="document" 
     transport="http://schemas.xmlsoap.org/soap/http" /> 
     <wsdl:operation name="GetContactInfoOperation"> 
     <soap:operation 
      soapAction="http://example.com/ZCntInfFr/GetContactInfoOperation" /> 
     <wsdl:input> 
      <soap:body use="literal" /> 
     </wsdl:input> 
     <wsdl:output> 
      <soap:body use="literal" /> 
     </wsdl:output> 
    </wsdl:operation> 
</wsdl:binding> 
<wsdl:service name="ZCntInfFr"> 
    <wsdl:port binding="tns:ZCntInfFrSOAP" name="ZCntInfFrSOAP"> 
     <soap:address location="http://server:8181/myrxs/ZCntInfFr" /> 
    </wsdl:port> 
</wsdl:service> 

当我在了SoapUI测试此,这里是请求/响应我接收:

了SoapUI请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:zcn="http://example.com/ZCntInfFr/"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <zcn:GetContactInfoOperation> 
     <ShipToAcct>099039</ShipToAcct> 
     </zcn:GetContactInfoOperation> 
    </soapenv:Body> 
</soapenv:Envelope> 

了SoapUI响应:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:zcn="http://example.com/ZCntInfFr/"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <zcn:GetContactInfoOperationResponse> 
     <Contacts> 
      <ContactData> 
       <ContactType>ADMIN</ContactType> 
       <ContactTypeDesc>Administrator</ContactTypeDesc> 
       <ContactName>Name</ContactName> 
       <ContactTitle/> 
       <ContactEmail>Email</ContactEmail> 
       <ContactPhone/> 
       <ContactExtension/> 
       <ContactFax/> 
      </ContactData> 
     </Contacts> 
     </zcn:GetContactInfoOperationResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 

回应正是我期望的。注意我正在取回一个联系人,这是正确的。

当我从.net调用的iSeries Web服务这里是请求/响应我看到在看提琴手时:

净请求

<?xml version="1.0" encoding="iso-8859-1"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
     <GetContactInfoOperation xmlns="http://www.mysitye.com/ZCntInfFr/"> 
      <ShipToAcct xmlns="">099039</ShipToAcct> 
     </GetContactInfoOperation> 
     </s:Body> 
    </s:Envelope> 

净响应

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:zcn="http://example.com/ZCntInfFr/"> 
    <soapenv:Header/> 
    <soapenv:Body> 
    <zcn:GetContactInfoOperationResponse> 
    <Contacts> 
    </Contacts> 
    </zcn:GetContactInfoOperationResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 

在这种情况下,当我从.Net调用它时,我收到一个空节点。没有联系人。

为了完整起见,这里是代理类,我从SvcUtil工具使用创建:

svcutil /n:*,Services.Web.Proxy.ISeriesContact /o:ContactProxy /s http://server:8181/ZCntInfFr.wsdl 

类:

namespace Services.Web.Proxy.ISeriesContact 
{ 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
    [System.ServiceModel.ServiceContractAttribute(Namespace = "http://example.com/ZCntInfFr/", ConfigurationName = "Services.Web.Proxy.ISeriesContact.ZCntInfFr")] 
    public interface ZCntInfFr 
    { 
     // CODEGEN: Parameter 'Contacts' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlElementAttribute'. 
     [System.ServiceModel.OperationContractAttribute(Action = "http://example.com/ZCntInfFr/GetContactInfoOperation", ReplyAction = "*")] 
     [System.ServiceModel.XmlSerializerFormatAttribute()] 
     [return: System.ServiceModel.MessageParameterAttribute(Name = "Contacts")] 
     Services.Web.Proxy.ISeriesContact.GetContactInfoOperationResponse GetContactInfoOperation(Services.Web.Proxy.ISeriesContact.GetContactInfoOperationRequest request); 

     [System.ServiceModel.OperationContractAttribute(Action = "http://example.com/ZCntInfFr/GetContactInfoOperation", ReplyAction = "*")] 
     System.Threading.Tasks.Task<Services.Web.Proxy.ISeriesContact.GetContactInfoOperationResponse> GetContactInfoOperationAsync(Services.Web.Proxy.ISeriesContact.GetContactInfoOperationRequest request); 
    } 

    /// <remarks/> 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.0.30319.33440")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://example.com/ZCntInfFr/")] 
    public partial class ContactDataType 
    { 

     private string[] itemsField; 

     private ItemsChoiceType[] itemsElementNameField; 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute("ContactEmail", typeof(string), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)] 
     [System.Xml.Serialization.XmlElementAttribute("ContactExtension", typeof(string), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)] 
     [System.Xml.Serialization.XmlElementAttribute("ContactFax", typeof(string), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)] 
     [System.Xml.Serialization.XmlElementAttribute("ContactName", typeof(string), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)] 
     [System.Xml.Serialization.XmlElementAttribute("ContactPhone", typeof(string), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)] 
     [System.Xml.Serialization.XmlElementAttribute("ContactTitle", typeof(string), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)] 
     [System.Xml.Serialization.XmlElementAttribute("ContactType", typeof(string), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)] 
     [System.Xml.Serialization.XmlElementAttribute("ContactTypeDesc", typeof(string), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)] 
     [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")] 
     public string[] Items 
     { 
      get 
      { 
       return this.itemsField; 
      } 
      set 
      { 
       this.itemsField = value; 
      } 
     } 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute("ItemsElementName", Order = 1)] 
     [System.Xml.Serialization.XmlIgnoreAttribute()] 
     public ItemsChoiceType[] ItemsElementName 
     { 
      get 
      { 
       return this.itemsElementNameField; 
      } 
      set 
      { 
       this.itemsElementNameField = value; 
      } 
     } 
    } 

    /// <remarks/> 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.0.30319.33440")] 
    [System.SerializableAttribute()] 
    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://example.com/ZCntInfFr/", IncludeInSchema = false)] 
    public enum ItemsChoiceType 
    { 

     /// <remarks/> 
     [System.Xml.Serialization.XmlEnumAttribute(":ContactEmail")] 
     ContactEmail, 

     /// <remarks/> 
     [System.Xml.Serialization.XmlEnumAttribute(":ContactExtension")] 
     ContactExtension, 

     /// <remarks/> 
     [System.Xml.Serialization.XmlEnumAttribute(":ContactFax")] 
     ContactFax, 

     /// <remarks/> 
     [System.Xml.Serialization.XmlEnumAttribute(":ContactName")] 
     ContactName, 

     /// <remarks/> 
     [System.Xml.Serialization.XmlEnumAttribute(":ContactPhone")] 
     ContactPhone, 

     /// <remarks/> 
     [System.Xml.Serialization.XmlEnumAttribute(":ContactTitle")] 
     ContactTitle, 

     /// <remarks/> 
     [System.Xml.Serialization.XmlEnumAttribute(":ContactType")] 
     ContactType, 

     /// <remarks/> 
     [System.Xml.Serialization.XmlEnumAttribute(":ContactTypeDesc")] 
     ContactTypeDesc, 
    } 

    /// <remarks/> 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.0.30319.33440")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://example.com/ZCntInfFr/")] 
    public partial class ContactsType 
    { 

     private ContactDataType[] contactDataField; 

     /// <remarks/> 
     [System.Xml.Serialization.XmlElementAttribute("ContactData", Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)] 
     public ContactDataType[] ContactData 
     { 
      get 
      { 
       return this.contactDataField; 
      } 
      set 
      { 
       this.contactDataField = value; 
      } 
     } 
    } 

    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] 
    [System.ServiceModel.MessageContractAttribute(WrapperName = "GetContactInfoOperation", WrapperNamespace = "http://example.com/ZCntInfFr/", IsWrapped = true)] 
    public partial class GetContactInfoOperationRequest 
    { 

     [System.ServiceModel.MessageBodyMemberAttribute(Namespace = "http://example.com/ZCntInfFr/", Order = 0)] 
     [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] 
     public string ShipToAcct; 

     public GetContactInfoOperationRequest() 
     { 
     } 

     public GetContactInfoOperationRequest(string ShipToAcct) 
     { 
      this.ShipToAcct = ShipToAcct; 
     } 
    } 

    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] 
    [System.ServiceModel.MessageContractAttribute(WrapperName = "GetContactInfoOperationResponse", WrapperNamespace = "http://example.com/ZCntInfFr/", IsWrapped = true)] 
    public partial class GetContactInfoOperationResponse 
    { 

     [System.ServiceModel.MessageBodyMemberAttribute(Namespace = "http://example.com/ZCntInfFr/", Order = 0)] 
     [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] 
     public Services.Web.Proxy.ISeriesContact.ContactsType Contacts; 

     public GetContactInfoOperationResponse() 
     { 
     } 

     public GetContactInfoOperationResponse(Services.Web.Proxy.ISeriesContact.ContactsType Contacts) 
     { 
      this.Contacts = Contacts; 
     } 
    } 

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
    public interface ZCntInfFrChannel : Services.Web.Proxy.ISeriesContact.ZCntInfFr, System.ServiceModel.IClientChannel 
    { 
    } 

    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
    public partial class ZCntInfFrClient : System.ServiceModel.ClientBase<Services.Web.Proxy.ISeriesContact.ZCntInfFr>, Services.Web.Proxy.ISeriesContact.ZCntInfFr 
    { 

     public ZCntInfFrClient() 
     { 
     } 

     public ZCntInfFrClient(string endpointConfigurationName) : 
      base(endpointConfigurationName) 
     { 
     } 

     public ZCntInfFrClient(string endpointConfigurationName, string remoteAddress) : 
      base(endpointConfigurationName, remoteAddress) 
     { 
     } 

     public ZCntInfFrClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
      base(endpointConfigurationName, remoteAddress) 
     { 
     } 

     public ZCntInfFrClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
      base(binding, remoteAddress) 
     { 
     } 

     [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] 
     Services.Web.Proxy.ISeriesContact.GetContactInfoOperationResponse Services.Web.Proxy.ISeriesContact.ZCntInfFr.GetContactInfoOperation(Services.Web.Proxy.ISeriesContact.GetContactInfoOperationRequest request) 
     { 
      return base.Channel.GetContactInfoOperation(request); 
     } 

     public Services.Web.Proxy.ISeriesContact.ContactsType GetContactInfoOperation(string ShipToAcct) 
     { 
      Services.Web.Proxy.ISeriesContact.GetContactInfoOperationRequest inValue = new Services.Web.Proxy.ISeriesContact.GetContactInfoOperationRequest(); 
      inValue.ShipToAcct = ShipToAcct; 
      Services.Web.Proxy.ISeriesContact.GetContactInfoOperationResponse retVal = ((Services.Web.Proxy.ISeriesContact.ZCntInfFr)(this)).GetContactInfoOperation(inValue); 
      return retVal.Contacts; 
     } 

     [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] 
     System.Threading.Tasks.Task<Services.Web.Proxy.ISeriesContact.GetContactInfoOperationResponse> Services.Web.Proxy.ISeriesContact.ZCntInfFr.GetContactInfoOperationAsync(Services.Web.Proxy.ISeriesContact.GetContactInfoOperationRequest request) 
     { 
      return base.Channel.GetContactInfoOperationAsync(request); 
     } 

     public System.Threading.Tasks.Task<Services.Web.Proxy.ISeriesContact.GetContactInfoOperationResponse> GetContactInfoOperationAsync(string ShipToAcct) 
     { 
      Services.Web.Proxy.ISeriesContact.GetContactInfoOperationRequest inValue = new Services.Web.Proxy.ISeriesContact.GetContactInfoOperationRequest(); 
      inValue.ShipToAcct = ShipToAcct; 
      return ((Services.Web.Proxy.ISeriesContact.ZCntInfFr)(this)).GetContactInfoOperationAsync(inValue); 
     } 
    } 
} 

我已经启用WCF跟踪,并没有什么在.svclog文件伸出。我一直在疯狂搜索,并发现WSDL中的minOccurs可能存在一些问题。我的想法是,这可能与.NET中的反序列化过程有关。作为一个便笺和练习,我能够使用WebClient对象调用SOAP服务,并且使用它中的联系人检索了正确的原始XML。这也导致我认为反序列化正在发生。

我也尝试使用wsdl.exe生成代理,但我仍然返回一个空的客户端节点。

我应该提及的另一件事是,当我在项目中将引用添加到服务引用的iSeries Web服务时,我得到完全相同的结果:没有联系人。

任何帮助,微推,意见,或方向将不胜感激。我已经为此工作了两天,但我仍然不完全理解这里发生的事情。

非常感谢您的帮助。

谢谢。

+0

您是否调试过iSeries的一面,看看它认为它是作为请求接收的?听起来像问题在那里,而不是在你的要求。 – bvstone 2014-09-22 17:05:55

+0

是的。在iSeries上工作的人已经调试了她的身边,并且她正在返回一个联系人,我可以使用SoapUI看到,但是当我从.Net使用它时不会看到。 – sloaniebaloney 2014-09-22 17:30:45

+0

在iSeries上他们可以看到返回的数据是你期望的,但是实际返回的数据是不同的。 iSeries或者返回一个联系人。我会和他们一起坐下来仔细检查,而不是在任何一方“假设”。 – bvstone 2014-09-22 19:54:38

回答

1

所以大声说出来。

事实证明,iSeries开发人员是手解析请求。所以即使从SoapUI和.Net生成的请求在功能上是等效的,结构也是不同的。这在iSeries代码中没有正确处理。

我不是iSeries的专家,但我建议我们使用标准xml库(如果存在的话),以便iSeries正确解析xml请求。

谢谢,宝石指点我在正确的方向。

0

我已经开发了许多服务,在iSeries中公开和使用数据,我为此作业严重推荐Scott Klement HTTPAPI。试试吧,你不会后悔的。

+0

我会看看。 – sloaniebaloney 2014-09-24 20:01:18