开发者

Deserialize a soap message

开发者 https://www.devze.com 2023-02-28 16:51 出处:网络
i have one provider extern that send开发者_如何学JAVA me that xml for test <?xml version=\"1.0\" encoding=\"utf-8\"?>

i have one provider extern that send开发者_如何学JAVA me that xml for test

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
   <AVCabeza transactionID="000032" xmlns="http://webservices.patito/Core/">
   <Solicitor entityID="WEST" systemType="WEB" />   
  </AVCabeza>
</soap:Header>
<soap:Body>
    <Availability xmlns:a="http://webservices.patito/Availability/" 
      xmlns:hc="http://webservices.patito/Common/" summaryOnly="true" 
      xmlns="http://webservices.patito/og/Availability.wsdl">
     <a:AvailabilityDetail availReqType="Room">
       <a:Estadia>
        <hc:StartDate>2009-01-05T00:00:00.0000000-05:00</hc:StartDate>
          <hc:EndDate>2009-01-06T00:00:00.0000000-05:00</hc:EndDate>
       </a:Estadia>
       <a:HotelSearchCriteria>              
            <a:HotelRef chainCode="WC"/>            
       </a:HotelSearchCriteria>
      </a:AvailabilityDetail>
     </Availability>
  </soap:Body>
</soap:Envelope>

I want deserializer so i did it

1) i used the xsd for generate c# class

2) Create a new project class library with the class generate.

The structure

WebServicesExterns (Project) --> Services (Folder) ---> all class

example

namespace WebServicesExterns.Services

<System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42"), _
 System.SerializableAttribute(), _
 System.Diagnostics.DebuggerStepThroughAttribute(), _
 System.ComponentModel.DesignerCategoryAttribute("code"), _
 System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://webservices.patito/Availability.wsdl")> _
Partial Public Class Availability




'''<comentarios/>
<System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42"),  _
System.SerializableAttribute(),  _
System.Diagnostics.DebuggerStepThroughAttribute(),  _
System.ComponentModel.DesignerCategoryAttribute("code"),  _
System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://webservices.patito/Core/"),  _
System.Xml.Serialization.XmlRootAttribute([Namespace]:="http://webservices.patito/Core/", IsNullable:=false)>  _
Partial Public Class AVCabeza

3) After create a test class for try deserializer

using WebServicesExterns.Services;
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Runtime.Remoting;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Serialization;
using NUnit.Framework;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Soap;


    [Test()]
    public void ShouldDeserializerSoapMessage()
    {
        var message = SoapToFromFile(@"C:\rq\Availability.xml");
        Assert.IsNotNull(message);
    }


    public object SoapToFromFile(string filePath)
    {
        IFormatter formatter;
        FileStream fileStream = null;
        Object objectFromSoap = null;            

        try
        {
            fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            formatter = new SoapFormatter();
            objectFromSoap = formatter.Deserialize(fileStream);
        }
        catch (Exception exception)
        {
            throw exception;
        }
        finally
        {
            if (fileStream != null) fileStream.Close();
        }
        return objectFromSoap;
    }

So, return that error

Parse Error, no assembly associated with Xml key "AVCabeza" "_P1"

Debugging i founded what _P1 is equal to "http://webservices.patito/Core/"

Apparently not found "Type" AVCabeza class

What's wrong?

New update

Look that was the provider give me

one folder with that structure

root
|
--  WSDL_XSD
|    |-XSD
|    |   files with extension .xsd
|    | 
|    --WS
|        files with extension .wsdl
|-- XMLSamples
     |-files with xml extension that contain soap messsages

well i delete of the xml (previous example) the head

<?xml version="1.0" encoding="utf-8"?>
<Availability xmlns:a="http://webservices.patito/Availability/" 
      xmlns:hc="http://webservices.patito/Common/" summaryOnly="true" 
      xmlns="http://webservices.patito/og/Availability.wsdl">
     <a:AvailabilityDetail availReqType="Room">
       <a:Estadia>
        <hc:StartDate>2009-01-05T00:00:00.0000000-05:00</hc:StartDate>
          <hc:EndDate>2009-01-06T00:00:00.0000000-05:00</hc:EndDate>
       </a:Estadia>
       <a:HotelSearchCriteria>              
            <a:HotelRef chainCode="WC"/>            
       </a:HotelSearchCriteria>
      </a:AvailabilityDetail>
</Availability>

and will try get deserializable availability object but fail this mark

not expected "<Availability .."

now in wsdl_xsd -> ws -> ws i see the availability exists so i think what availability is wrap to availabilitydetail (real request) which is the object i cant delete availability tag because it have namespace spacefications for childs tags

what think about it?

maybe if i delete availability and insert namespaces (somehow) i could get my de-serializer object


SoapFormatter is not the XML Serializer. You should use the XmlSerializer class.

Also, this is an entire SOAP Message. You'd be better off having them give you the WSDL and using "Add Service Reference". This would give you classes that will do the serialization and deserialization for you.


When you use xsd.exe to generate C# classes from that XML document, in the first step you will get 5 individual .xsd files, providing the XSD Schema "inferred" from the message. (There are numerous XSD files because you're using numerous XML namespaces in that message)

In particular, XSD.exe will generate code to describe the SOAP Envelope, including the body and header. This is probably not something you want or need to be doing, but the xsd.exe tool infers types for the entire XML document.

Also, the inference engine within xsd.exe is imprecise. For example, the "StartDate" and "EndDate" child elements of the Estadia element appear to be dates. But xsd.exe won't make that assumption; it will generate an XML schema that marks those things as strings. There are other similar assumptions that xsd.exe makes as it infers. In all cases you probably want to modify the generated xsd files, to match what you truly expect. In the case of StartDate and EndDate, you want to modify the type from xs:string to xs:dateTime.

At that point you can run xsd.exe again, on the .xsd files, using the /c switch, to generate .cs source code. Compile that to get classes that can be used in serialization.

To de-serialize using that generated code, you'd do something like this:

  XmlSerializer s1 = new XmlSerializer(typeof(Carlos.Envelope));
  Envelope envelope = null;
  using(var reader= System.IO.File.OpenText("SampleMessage.xml"))
  {
      envelope = (Envelope) s1.Deserialize(reader);
  }

Then you can open up that Envelope object and get at the various data within it.


Stepping back, you can see that you probably shouldn't be doing this. It's useful and handy to see a sample message, to show you what things ought to look like on the wire. But when generating code to handle classes that serialize to those messages, it's better to start with the source XSD - which is probably available at the service end. This is what John Saunders said in his reply.

If your people can produce a sample message, they probably have the XSD (or the WSDL, which is equivalent) for that message. This would eliminate the requirement for you to infer the xsd, and then modify it to change the broken assumptions, via the inexact process I described above.

The only time you'd need to do that is if you somehow lost the original XSD/WSDL, and you needed to regenerate it.

0

精彩评论

暂无评论...
验证码 换一张
取 消