2013-09-25 5 views
1

Я написал код C# для XML-запроса Soap, я проверил этот код, генерирующий класс XML.Мыльный запрос и ответ в C#

Мой вопрос в том, как отправить запрос и получить ответ с использованием кода C#.

Пожалуйста, будьте любезны с моими простыми или основными ошибками, потому что я новичок в XML, но ваша помощь будет действительно оценена.

SOAP XML запрос:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ce="http://www." xmlns:os="http://www.domainname.com/schema/soap/v1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    <soapenv:Header /> 
    <soapenv:Body> 
     <ce:message> 
      <ce:m_control> 
       <os:control_timestamp>2001-12-31T12:00:00</os:control_timestamp> 
       <os:message_id>000000000000000000000000000000000</os:message_id> 
       <os:message_type>Contract Enquiry Request</os:message_type> 
       <os:message_version>ce/v2.2/NameContractRequest</os:message_version> 
       <os:expected_response_type>synchronous</os:expected_response_type> 
       <os:initiator_id>initiator_id</os:initiator_id> 
       <os:initiator_orchestration_id>initiator_orchestration_id</os:initiator_orchestration_id> 
       <os:KeyInfo> 
        <ds:X509Data> 
         <ds:X509IssuerSerial> 
          <ds:X509IssuerName>CN=OSIS Customer CA, O=Origo Secure Internet Services Ltd., CN=OSIS Customer CA</ds:X509IssuerName> 
          <ds:X509SerialNumber>111111111111111111111111111111111111</ds:X509SerialNumber> 
         </ds:X509IssuerSerial> 
         <ds:X509SubjectName>C=GB, O=FirmID3400010000023NR11QQ, OU=CPS - www.unipass.co.uk/cps, OU=Warning/Terms of Use - www.unipass.co.uk/tou, OU=EmployeeID10101101010101, OU=TPSP2, OU=BPNR1 1QQ, CN=Testt Orgg/[email protected]</ds:X509SubjectName> 
        </ds:X509Data> 
       </os:KeyInfo> 
       <os:responder_id>os:responder_id</os:responder_id> 
      </ce:m_control> 
      <ce:m_content> 
       <ce:b_control> 
        <ce:contract_enquiry_reference>TestRequest</ce:contract_enquiry_reference> 
       </ce:b_control> 
       <ce:intermediary> 
        <ce:FirmFSARef id="idvalue14">456123</ce:FirmFSARef> 
       </ce:intermediary> 
       <ce:request_scope> 
        <ce:contract_details_required_ind>No</ce:contract_details_required_ind> 
        <ce:valuation_currency>GBP</ce:valuation_currency> 
        <ce:fund_code_type_required>SEDOL</ce:fund_code_type_required> 
        <ce:valuation_request ce:type="Current" /> 
       </ce:request_scope> 
       <ce:contract> 
        <ce:contract_reference_number>TL12345678</ce:contract_reference_number> 
       </ce:contract> 
      </ce:m_content> 
     </ce:message> 
    </soapenv:Body> 
</soapenv:Envelope> 
#################################### ############ C# code ##################

Руководство CEGuid = Guid.NewGuid(); string GuidString = CEGuid.ToString();

 string CEVersion = ""; 
     string URL = ""; 
     string ResponderId = ""; 
     string ContractDetailsRequired = "Yes"; 

     using (XmlTextWriter xmlRequestWriter = new XmlTextWriter(@"C:/Unipass/PensionRequest.xml", Encoding.UTF8)) 
     { 
      xmlRequestWriter.WriteStartDocument(); 

      xmlRequestWriter.WriteComment("This file is generated by the program."); 

      xmlRequestWriter.WriteStartElement("soapenv:Envelope"); 

      xmlRequestWriter.WriteAttributeString("xmlns:soapenv", null, "http://schemas.xmlsoap.org/soap/envelope/"); 
      xmlRequestWriter.WriteAttributeString("xmlns:ce", null, "http://www.WhateveryDomain.com/schema/ce/v2.2/WhateverRequest"); 
      xmlRequestWriter.WriteAttributeString("xmlns:os", null, "http://www.WhateveryDomain.com/schema/soap/v1"); 
      xmlRequestWriter.WriteAttributeString("xmlns:ds", null, "http://www.w3.org/2000/09/xmldsig#"); 

      xmlRequestWriter.WriteStartElement("soapenv:Header"); 
      xmlRequestWriter.WriteEndElement(); 

      xmlRequestWriter.WriteStartElement("ce:message"); 
      xmlRequestWriter.WriteStartElement("ce:m_control"); 
      xmlRequestWriter.WriteElementString("os:control_timestamp", DateTime.Now.ToString("s")); 
      xmlRequestWriter.WriteElementString("os:message_id", GuidString); 
      xmlRequestWriter.WriteElementString("os:message_type", "Contract Enquiry Request"); 
      xmlRequestWriter.WriteElementString("os:message_version", "ce/v2.2/WhateverRequest"); 
      xmlRequestWriter.WriteElementString("os:expected_response_type", "synchronous"); 
      xmlRequestWriter.WriteElementString("os:initiator_id", "initiator_id"); 
      xmlRequestWriter.WriteElementString("os:initiator_orchestration_id", "initiator_orchestration_id"); 
      xmlRequestWriter.WriteStartElement("os:KeyInfo"); 
      xmlRequestWriter.WriteStartElement("ds:X509Data"); 
      xmlRequestWriter.WriteStartElement("ds:X509IssuerSerial"); 
      xmlRequestWriter.WriteElementString("ds:X509IssuerName", "CN=OSIS Customer CA, O=Origo Secure Internet Services Ltd., CN=OSIS Customer CA"); 
      xmlRequestWriter.WriteElementString("ds:X509SerialNumber", "111111111111111111111111111111111"); 
      xmlRequestWriter.WriteEndElement(); 
      xmlRequestWriter.WriteElementString("ds:X509SubjectName", "C=GB, O=FirmID3400010000023NR11QQ, OU=CPS - www.unipass.co.uk/cps, OU=Warning/Terms of Use - www.unipass.co.uk/tou, OU=EmployeeID01200012000003, OU=TPSP2, OU=BPNR1 1QQ, CN=Testt Orgg/[email protected]"); 
      xmlRequestWriter.WriteEndElement(); 
      xmlRequestWriter.WriteEndElement(); 
      xmlRequestWriter.WriteElementString("os:responder_id", "os:responder_id"); 
      xmlRequestWriter.WriteEndElement(); 



      xmlRequestWriter.WriteStartElement("ce:m_content"); 
      xmlRequestWriter.WriteStartElement("ce:b_control"); 
      xmlRequestWriter.WriteElementString("ce:contract_enquiry_reference", "TestRequest"); 
      xmlRequestWriter.WriteEndElement(); 
      xmlRequestWriter.WriteStartElement("ce:intermediary"); 
      xmlRequestWriter.WriteStartElement("ce:FirmFSARef"); 
      xmlRequestWriter.WriteElementString("id", "456123");//="idvalue14"> 
      xmlRequestWriter.WriteEndElement(); 
      xmlRequestWriter.WriteEndElement(); 
      xmlRequestWriter.WriteStartElement("ce:request_scope"); 
      xmlRequestWriter.WriteElementString("ce:contract_details_required_ind", "Yes"); 
      xmlRequestWriter.WriteElementString("ce:valuation_currency", "GBP"); 
      xmlRequestWriter.WriteElementString("ce:fund_code_type_required", "SEDOL"); 
      xmlRequestWriter.WriteStartElement("ce:valuation_request"); 
      xmlRequestWriter.WriteElementString("ce:type", "Current");//"ce:type","Current" 
      xmlRequestWriter.WriteEndElement(); 
      xmlRequestWriter.WriteEndElement(); 
      xmlRequestWriter.WriteStartElement("ce:contract"); 
      xmlRequestWriter.WriteElementString("ce:contract_reference_number", "PP12345678"); 
      xmlRequestWriter.WriteEndElement(); 
      xmlRequestWriter.WriteEndElement(); 
      xmlRequestWriter.WriteEndElement(); 

      xmlRequestWriter.WriteEndElement(); 
      xmlRequestWriter.WriteEndDocument(); 
      xmlRequestWriter.Flush(); 

Пожалуйста, не могли бы вы рассказать мне, как отправить запрос и получить ответ от службы WCF, используя вышеуказанный код.

Хотя я добавил ссылку wsdl, но не знаю, как передать XmlElement [] в строке ниже.

serviceReference.getDetail (ref XmlElement [] Any);

Предлагаемый метод относится к классу Reference.

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
    [System.ServiceModel.ServiceContractAttribute(Namespace="http://www.domainname.com/whatever/webname/schema/ce/v2.2/NameContractServic" + 
     "e", ConfigurationName="TestingPension.NameContractServiceDetailType")] 
    public interface NameContractServiceDetailType { 

     // CODEGEN: Generating message contract since the wrapper namespace (http://www.domainname.com/schema/ce/v2.2/NameContractRequest) of message getDetailRequest does not match the default value (http://www.domainname.com/name/name/schema/ce/v2.2/NameContractService) 
     [System.ServiceModel.OperationContractAttribute(Action="http://www.origostandards.com/schema/ce/v2.2/CEPensionSingleContract#getDetail", ReplyAction="*")] 
     [System.ServiceModel.FaultContractAttribute(typeof(SoapReqResWebApplication.TestingPension.Error[]), Action="http://www.domainname.com/schema/ce/v2.2/NameContract#getDetail", Name="errors", Namespace="http://www.domainname.com/schema/tech/v1.0/SOAPFaultDetail")] 
     [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)] 
     SoapReqResWebApplication.TestingPension.getDetailResponse getDetail(SoapReqResWebApplication.TestingPension.getDetailRequest request); 
    } 

    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] 
    [System.ServiceModel.MessageContractAttribute(WrapperName="message", WrapperNamespace="http://www.domainname.com/schema/ce/v2.2/NameContractRequest", IsWrapped=true)] 
    public partial class getDetailRequest { 

     [System.ServiceModel.MessageBodyMemberAttribute(Namespace="", Order=0)] 
     [System.Xml.Serialization.XmlAnyElementAttribute()] 
     public System.Xml.XmlElement[] Any; 

     public getDetailRequest() { 
     } 

     public getDetailRequest(System.Xml.XmlElement[] Any) { 
      this.Any = Any; 
     } 
    } 

@CodeCaster Я попробовал ваш код, как: вар documentToSend = новый XmlDocument(); //// TODO: добавить все элементы, которые вы хотели
используя (XmlTextWriter xmlRequestWriter = новый XmlTextWriter (@ "C: /Unipass/Request.xml", Encoding.UTF8)) { xmlRequestWriter.WriteStartDocument(); xmlRequestWriter.WriteStartElement ("ce: message"); xmlRequestWriter.WriteEndElement(); xmlRequestWriter.WriteEndDocument(); xmlRequestWriter.Flush(); documentToSend.Save (xmlRequestWriter); //// Создайте массив с корневым узлом сообщения только как элемент. var xmlToSend = new XmlElement [] {documentToSend.DocumentElement}; // xmlToSend = null
} Может быть, я совершенно ошибаюсь, пожалуйста, скажите мне, почему xmlToSend равно null.

ответ

0

Похоже, что прокси-генератор WCF не может создать класс из предоставленного WSDL/XSD, учитывая, что сгенерированная сигнатура метода - getDetailRequest(System.Xml.XmlElement[] Any). Что такое инструмент, как SoapUI сказать о WSDL?

Способ решения этой проблемы - действительно вручную генерировать сообщение, которое является только блоком <ce:message>..</ce:message>. WCF будет обернуть его в надлежащий конверт SOAP при вызове метода службы.

Вам придется поиграть немного с XmlDocument класса, но я думаю, что что-то, как это будет делать:

// Create an XmlDocument and fill it 
var documentToSend = new XmlDocument(); 

// TODO: add all elements you like 

// Create an array with the root message node as only element. 
var xmlToSend = new XmlElement[] { documentToSend.DocumentElement }; 

// Call the service. 
var response = serviceReference.getDetail(xmlToSend); 

Другой способ вручную воссоздать класс запроса в C# и заполнить и сериализуйте экземпляр его в XML при отправке запроса.Конечным способом было бы исправить XML, поэтому Add Service Reference (SvcUtil) может генерировать классы из метаданных службы.

Что касается редактирования, вы не записываете элементы XML в documentToSend, но записываете их в свой файл.

+0

, пожалуйста, вы можете отправить мне образец, который пишет такие элементы, как и , для docmentToSend. Я могу сделать это, используя только xmlTextWriter, а не xmlElement. – user1132134

+0

См. ['XmlDocument.CreateNode()'] (http://msdn.microsoft.com/en-us/library/1s01fd90.aspx). – CodeCaster

+0

CodeCaster, пожалуйста, вы можете дать мне подсказку, как создать/добавить XmlElement . Создание простого узла легко, но я стараюсь добавить «** **» – user1132134

1

Кажется, что вы пишете код вручную, чтобы сериализовать сообщения в SOAP/XML. Пример запроса SOAP - это фактический экземплярный документ, а не WSDL, да? Это одна из тех вещей, которые WCF делает для вас - вам не нужно создавать собственные SOAP-сообщения.

В WCF вы фокусируетесь на типах объектов, которые хотите передать, и на операциях, которые вы хотите поддерживать. Затем WCF делает весь тяжелый подъем сериализации SOAP для вас. Это главное в WCF.

Это довольно трудно расшифровать из вашего образца SOAP сообщения, что именно вы пытаетесь сделать, так что я бы рекомендовал смотреть на один из простых образцов WCF, скажем, здесь

http://msdn.microsoft.com/en-us/library/vstudio/ms751514(v=vs.90).aspx

Получить простой один запуск и запуск с использованием wsHttpBinding или basicHttpBinding (это привязки SOAP в WCF). Затем захватите HTTP-запрос, используя Fiddler или аналогичный, и посмотрите, что сделал WCF для вас с точки зрения генерации оболочки SOAP.

Затем вы можете перевести это в свой собственный случай.

+0

Спасибо за ваш ответ Майк, я уже сделал это, что вы сказали, но мои требования совершенно разные, и, кроме того, у меня мало опыта работы с WCF. Я создал простой WCF и добавил метод ADD, и я использовал в своем приложении, как этот protected int sendSoapMessage() int result; using (var cs = new CalculatorSoap.Service1Client ("BasicHttpBinding_IService1")) var com = new CalculatorSoap.CompositeType(); com.Value1 = 3; com.Value2 = 5; result = cs.Add (com); результат возврата; – user1132134

Смежные вопросы