我花了无数个小时研究这个问题,并尝试了很多不同的事情。一些背景...我在SSIS模块中使用C#代码来尝试反序列化SOAP XML流。我以前能够反序列化XML流,但是这个比我之前参与的那些要复杂得多。
我已经确认我用来填充我的流的字符串对于结果是正确的,并且我到达了我的绳子的末尾。
这是我用来尝试反序列化的方法。您可以看到我已经包含了几个已注释掉的部分,以展示我用来尝试实现此功能的其他一些方法:
private Envelope GetWebServiceResultFromStream(StreamReader str)
{
bool b = true;
Envelope xmlResponse = null;
String xmlPayload = "";
//Deserialize our XML
try
{
//System.Runtime.Serialization.Formatters.Soap.SoapFormatter soapFormatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
//using (Stream savestream = str.BaseStream)
//{
// xmlResponse = (Envelope)soapFormatter.Deserialize(savestream);
//}
System.Xml.Serialization.XmlSerializer sr = new System.Xml.Serialization.XmlSerializer(typeof(Envelope));
using (Stream savestream = str.BaseStream)
{
StreamReader streamreader = new StreamReader(savestream, Encoding.UTF8);
xmlPayload = streamreader.ReadToEnd();
//xmlPayload = System.Security.SecurityElement.Escape(xmlPayload);
//xmlPayload = xmlPayload.Replace("&", "&");
//xmlPayload = xmlPayload.Replace("&", "&");
xmlPayload = xmlPayload.Replace("'", "'");
//xmlPayload = xmlPayload.Replace("soap:Envelope", "Envelope");
File.WriteAllText(@"myxml.xml",xmlPayload);
byte[] byteArray = Encoding.UTF8.GetBytes(xmlPayload);
MemoryStream secondstream = new MemoryStream(byteArray);
secondstream.Position = 0;
xmlResponse = sr.Deserialize(secondstream) as Envelope;
//xmlResponse = (Envelope)DeserializeFromXml<Envelope>(xmlPayload);
//XmlDocument doc = new XmlDocument();
//doc.Load(secondstream);
//XmlNodeReader reader = new XmlNodeReader(doc);
//using (reader)
//{
// xmlResponse = sr.Deserialize(reader) as Envelope;
//}
//System.Runtime.Serialization.Formatters.Soap.SoapFormatter soapFormatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
//xmlResponse = (Envelope)soapFormatter.Deserialize(secondstream);
}
//XmlDocument xmlSoapRequest = new XmlDocument();
//using (Stream savestream = str.BaseStream)
//{
// using (StreamReader readStream = new StreamReader(savestream, Encoding.UTF8))
// {
// xmlSoapRequest.Load(readStream);
// xmlPayload = xmlSoapRequest.SelectSingleNode("//Envelope/Body/GetRequisitionByDateResponse/").InnerText;
// }
//}
}
catch (Exception ex)
{
DumpException(ex);
this.ComponentMetaData.FireInformation(54, "", "Failed to deserialize: " + ex.Message + " Inner: " + ex.InnerException + " Source: " + ex.Source, "", 43, ref b);
}
return xmlResponse;
}
public static T DeserializeFromXml<T>(string xml)
{
T result;
var ser = new XmlSerializer(typeof(T));
using (var tr = new StringReader(xml))
{
result = (T)ser.Deserialize(tr);
}
return result;
}
我正在使用通过将响应提供给XML到C#转换器(http://xmltocsharp.azurewebsites.net/)而生成的c#类。不幸的是,似乎这些类太复杂而无法放在这里(帖子有30k字符限制),所以它已被粘贴在这里: http://txt.do/d91eo
我还贴了一个示例回复: http://txt.do/d91eb
我已经咨询了wsdl,看起来许多DateTime字段正在通过转换器读取为字符串。我不确定这是否是一个问题,但我已尽力替换这些数据类型并且错误仍然存在。
以下是我的错误的屏幕截图: http://imgur.com/a/objJq
我尝试过的其他事情:
替换整个xml文档中的无效字符(我发现它已经这样做了,除了一些“'”字符的情况)。
删除了名称空间。
将所有类标记为Serializable。
SSIS中的Web服务对象(抛出错误并且不允许我输入要发送的任何变量)。
使用返回结果的多个变体重新生成类列表。
答案 0 :(得分:1)
找到它
首先将UTF8添加到StreamReader:new StreamReader(FILENAME,Encoding.UTF8);
这是你的根类
[XmlRoot(ElementName = "Envelope", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public class Envelope
{
}
这是你的第一行XML
<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">
比较命名空间
答案 1 :(得分:1)
以下代码正在运行,没有例外。由于尺寸限制,我不能包括类。注意Class Envelope的命名空间我用“/”替换了“ - ”。构造类Envelope但所有属性都为null,因为命名空间与xml不一致。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication50
{
class Program
{
static void Main(string[] args)
{
new Test();
}
}
public class Test
{
const string FILENAME = @"c:\temp\test2.xml";
public Test()
{
StreamReader reader = new StreamReader(FILENAME, Encoding.UTF8);
GetWebServiceResultFromStream(reader);
}
private Envelope GetWebServiceResultFromStream(StreamReader str)
{
bool b = true;
Envelope xmlResponse = null;
String xmlPayload = "";
//Deserialize our XML
try
{
//System.Runtime.Serialization.Formatters.Soap.SoapFormatter soapFormatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
//using (Stream savestream = str.BaseStream)
//{
// xmlResponse = (Envelope)soapFormatter.Deserialize(savestream);
//}
System.Xml.Serialization.XmlSerializer sr = new System.Xml.Serialization.XmlSerializer(typeof(Envelope));
using (Stream savestream = str.BaseStream)
{
StreamReader streamreader = new StreamReader(savestream, Encoding.UTF8);
xmlPayload = streamreader.ReadToEnd();
//xmlPayload = System.Security.SecurityElement.Escape(xmlPayload);
//xmlPayload = xmlPayload.Replace("&", "&");
//xmlPayload = xmlPayload.Replace("&", "&");
xmlPayload = xmlPayload.Replace("'", "'");
//xmlPayload = xmlPayload.Replace("soap:Envelope", "Envelope");
File.WriteAllText(@"myxml.xml",xmlPayload);
byte[] byteArray = Encoding.UTF8.GetBytes(xmlPayload);
MemoryStream secondstream = new MemoryStream(byteArray);
secondstream.Position = 0;
xmlResponse = sr.Deserialize(secondstream) as Envelope;
//xmlResponse = (Envelope)DeserializeFromXml<Envelope>(xmlPayload);
//XmlDocument doc = new XmlDocument();
//doc.Load(secondstream);
//XmlNodeReader reader = new XmlNodeReader(doc);
//using (reader)
//{
// xmlResponse = sr.Deserialize(reader) as Envelope;
//}
//System.Runtime.Serialization.Formatters.Soap.SoapFormatter soapFormatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
//xmlResponse = (Envelope)soapFormatter.Deserialize(secondstream);
}
//XmlDocument xmlSoapRequest = new XmlDocument();
//using (Stream savestream = str.BaseStream)
//{
// using (StreamReader readStream = new StreamReader(savestream, Encoding.UTF8))
// {
// xmlSoapRequest.Load(readStream);
// xmlPayload = xmlSoapRequest.SelectSingleNode("//Envelope/Body/GetRequisitionByDateResponse/").InnerText;
// }
//}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
//DumpException(ex);
//this.ComponentMetaData.FireInformation(54, "", "Failed to deserialize: " + ex.Message + " Inner: " + ex.InnerException + " Source: " + ex.Source, "", 43, ref b);
}
return xmlResponse;
}
public static T DeserializeFromXml<T>(string xml)
{
T result;
var ser = new XmlSerializer(typeof(T));
using (var tr = new StringReader(xml))
{
result = (T)ser.Deserialize(tr);
}
return result;
}
}
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Body", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public Body Body { get; set; }
[XmlAttribute(AttributeName = "soap", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Soap { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xsi { get; set; }
[XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xsd { get; set; }
}
}