2011-04-26 127 views
3

我有一个供应商的extern说送我,XML测试反序列化SOAP消息

<?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> 

我想解串器,所以我做到了

1)我使用的XSD的生成C#类

2)用类generate创建一个新的项目类库。

结构

WebServicesExterns(项目) - >服务(文件夹) --->所有类

例如

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)创建尝试一个测试类之后解串器

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; 
    } 

因此,返回该错误

解析错误,没有与XML密钥 “AVCabeza” “_p1缔合体”

调试我创办什么_p1等于 “HTTP://webservices.patito/Core/”

显然没有找到“类型”AVCabeza类

怎么了?这是供应商

新的更新

看给我

一个文件夹与结构

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

以及我删除XML(前面的例子)头部

<?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> 

并将尝试获取des erializable供应对象,但现在失败这个标志

not expected "<Availability .." 

在wsdl_xsd - > WS - > WS我看到的可用性存在,所以我觉得可用性换到availabilitydetail(实际要求),这是我不能删除 可用性对象标签,因为它具有儿童标签的名称空间spacefications

是什么想法呢?

也许如果我删除可用性和插入命名空间(在某种程度上)我能得到我的解串对象

回答

3

SoapFormatter不是XML序列化。您应该使用XmlSerializer类。

此外,这是一个完整的SOAP消息。您最好让他们为您提供WSDL并使用“添加服务参考”。这会给你一些可以为你做序列化和反序列化的类。

+0

对不起,我不能添加Web引用,因为存在的共同对象,我使用5 8服务和它导致冲突,所以我创建了一个代理与WSDL和生成所有类。非常感谢 – 2011-04-26 20:22:07

+1

如果你使用WSDL创建了一个代理,那么你做了和“添加Web引用”一样的事情。这意味着你不需要做你自己的序列化。 – 2011-04-26 20:23:09

2

当您使用xsd.exe从该XML文档生成C#类时,第一步将获得5个单独的.xsd文件,从消息中提供 XSD Schema“推断”。 (因为在该消息中使用了大量的XML名称空间,所以有许多XSD文件)

特别是,XSD.exe将生成代码来描述SOAP Envelope,其中包括正文和头文件。这可能不是您想要或需要做的事情,但是xsd.exe工具会推断整个XML文档的类型。

此外,xsd.exe中的推理引擎是 不准确。例如,Estadia元素的“StartDate”和“EndDate”子元素显示为日期。但是xsd.exe不会做出这样的假设;它将生成一个XML模式,将这些事情标记为字符串。还有其他类似的假设,即xsd.exe在推断时做出的。在所有情况下,您可能都希望修改生成的xsd文件,以匹配您真正期望的内容。对于StartDate和EndDate,您想要将类型从xs:string修改为xs:dateTime

此时,您可以使用/ c开关在.xsd文件中再次运行xsd.exe 以生成.cs源代码。编译获取可用于序列化的类。

要使用生成的代码,你会做这样的事反序列化:

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

然后你可以打开那个信封对象,并在其内的各种数据得到。


退一步,你可以看到你可能不应该这样做。查看示例消息很有用也很方便,可以告诉你线路上应该看起来像什么东西。但是,当生成代码来处理序列化为这些消息的类时,最好从源XSD开始 - 这可能在服务端可用。约翰桑德斯在答复中说道。

如果您的人员可以生成示例消息,那么他们可能拥有该消息的XSD(或等效的WSDL)。这将消除您推断xsd的要求,然后通过上述不精确的过程对其进行修改以更改破碎的假设。

你唯一需要做的就是如果你以某种方式丢失了原来的XSD/WSDL,并且你需要重新生成它。

+0

谢谢Cheeso,那是提供者给我的 一个文件夹与它 根 - WSDL_XSD | | -XSD(扩展名为.xsd的文件) | --WS(带扩展名的文件。WSDL) | - XMLSamples(含皂形式交往与XML扩展名的文件) 对不起,如果我的错误,但我的想法是生成C#类XSD 机构获取XML请求 的后解串后立即获得支正确的c#类 和后反射litte。我尝试和尝试的 一,二和许多方法,但我甚至不能 我承认我是新的XML。 – 2011-04-30 17:26:41