我有一个提供商extern给我发送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>
我想反序列化,所以我做了
1)我使用xsd生成c#class
2)使用类generate创建一个新的项目类库。
结构
WebServicesExterns(项目) - &GT;服务(文件夹) ---&GT;全班
例如
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)为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;
}
所以,返回该错误
解析错误,没有与Xml键“AVCabeza”“_ P1”关联的程序集
调试我创建的_P1等于“http://webservices.patito/Core/”
显然未找到“Type”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>
并尝试获取可反序列化的可用性对象但未通过此标记
not expected "<Availability .."
现在在wsdl_xsd - &gt; ws - &gt;我看到可用性存在所以我认为什么可用性包装到availabilitydetail(真实请求),这是我无法删除的对象 可用性标记,因为它具有childs标记的命名空间spacefications
怎么想呢?也许如果我删除可用性并插入命名空间(不知何故)我可以得到我的反序列化器对象
答案 0 :(得分:3)
SoapFormatter不是XML Serializer。您应该使用XmlSerializer类。
此外,这是一个完整的SOAP消息。让他们为您提供WSDL并使用“添加服务参考”会更好。这将为您提供将为您执行序列化和反序列化的类。
答案 1 :(得分:2)
当您使用xsd.exe从该XML文档生成C#类时,在第一步中您将获得5个单独的.xsd文件, XSD架构从邮件中“推断”。 (有许多XSD文件,因为您在该消息中使用了大量的XML命名空间)
特别是,XSD.exe将生成用于描述SOAP Envelope的代码,包括正文和标题。这可能不是您想要或不需要做的事情,但xsd.exe工具推断整个XML文档的类型。
此外,xsd.exe中的推理引擎是
不精确。例如,Estadia元素的“StartDate”和“EndDate”子元素似乎是日期。但xsd.exe不会做出这样的假设;它将生成一个XML模式,将这些内容标记为 strings 。 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);
}
然后,您可以打开该Envelope对象并获取其中的各种数据。
退后一步,你可以看到你可能不应该这样做。查看示例消息非常有用且方便,以向您展示线路上应该是什么样的内容。但是当生成代码来处理序列化到这些消息的类时,最好从源XSD开始 - 这可能在服务端可用。这就是约翰桑德斯在回答中所说的话。
如果您的员工可以生成示例消息,那么他们可能拥有该消息的XSD(或等效的WSDL)。这将消除您推断xsd的要求,然后通过我上面描述的不精确的过程修改它来改变破坏的假设。
您需要这样做的唯一时间是,如果您以某种方式丢失了原始XSD / WSDL,并且您需要重新生成它。