2014-09-22 141 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