无法使用 DataContractSerializer 反序列化 xml
Can't Deserialize xml using DataContractSerializer
我无法将此 XML 反序列化为对象,我不知道这有什么问题:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ProcessOneWayEvent xmlns="http://schemas.microsoft.com/sharepoint/remoteapp/">
<properties xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CultureLCID>1033</CultureLCID>
</properties>
</ProcessOneWayEvent>
</s:Body>
</s:Envelope>
这是一个现成的sample,有没有解决方法,因为我不能在请求中修改,所以我的模型有什么问题吗?是否有任何解决方案可以在不使用 XmlSerializer
的情况下反序列化 XML
我没有立即明白为什么它不起作用,但一种替代方法是使用 System.Xml.Serialization.XmlSerializer
。
首先通过将 XML 复制到新的 class 来创建适当的信封 classes(编辑 → 选择性粘贴 → 将 XML 粘贴为 类)
然后以此为例进行反序列化:
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(request);
using (var stream = new MemoryStream(byteArray))
{
var serializer = new XmlSerializer(typeof(Envelope));
Envelope response = (Envelope)serializer.Deserialize(stream);
Console.WriteLine(JsonConvert.SerializeObject(response));
}
尝试以下操作:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
string xml = File.ReadAllText(FILENAME);
StringReader sReader = new StringReader(xml);
XmlReader reader = XmlReader.Create(sReader);
XmlSerializer serializer = new XmlSerializer(typeof(Envelope));
Envelope envelope = (Envelope)serializer.Deserialize(reader);
}
}
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public Body Body { get; set; }
}
public class Body
{
[XmlElement(ElementName = "ProcessOneWayEvent", Namespace = "http://schemas.microsoft.com/sharepoint/remoteapp/")]
public ProcessOneWayEvent ProcessOneWayEvent { get; set; }
}
public class ProcessOneWayEvent
{
public Properties properties { get; set; }
}
public class Properties
{
public string CultureLCID { get; set; }
}
}
使用 Xml Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
string xml = File.ReadAllText(FILENAME);
XDocument doc = XDocument.Parse(xml);
string CultureLCID = (string)doc.Descendants().Where(x => x.Name.LocalName == "CultureLCID").FirstOrDefault();
}
}
}
Body
和 SPRemoteEventProperties
需要在 "http://schemas.microsoft.com/sharepoint/remoteapp/"
命名空间中:
[DataContract(Name = "Body", Namespace = "http://schemas.microsoft.com/sharepoint/remoteapp/")]
public class Body
{
[DataMember(Name = "ProcessOneWayEvent")]
public ProcessOneWayEvent ProcessOneWayEvent;
}
[DataContract(Name = "properties", Namespace = "http://schemas.microsoft.com/sharepoint/remoteapp/")]
public class SPRemoteEventProperties
{
[DataMember(Name = "CultureLCID") ]
public int CultureLCID { get; set; }
}
DataContractAttribute.Namespace
控制数据契约对象的数据成员元素序列化到的命名空间,以及数据契约对象时根元素的命名空间是根元素。由于元素 <ProcessOneWayEvent xmlns="http://schemas.microsoft.com/sharepoint/remoteapp/">
声明了一个新的默认 XML 命名空间,元素本身及其子元素都在这个命名空间中。因此,包含数据协定对象 Body
必须相应地设置其数据成员命名空间。至于 <properties xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
,i:
命名空间不是默认命名空间,因此实际上没有元素分配给此命名空间,并且 SPRemoteEventProperties
类型不应将自身分配给它。
固定 fiddle here.
我无法将此 XML 反序列化为对象,我不知道这有什么问题:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ProcessOneWayEvent xmlns="http://schemas.microsoft.com/sharepoint/remoteapp/">
<properties xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CultureLCID>1033</CultureLCID>
</properties>
</ProcessOneWayEvent>
</s:Body>
</s:Envelope>
这是一个现成的sample,有没有解决方法,因为我不能在请求中修改,所以我的模型有什么问题吗?是否有任何解决方案可以在不使用 XmlSerializer
的情况下反序列化 XML我没有立即明白为什么它不起作用,但一种替代方法是使用 System.Xml.Serialization.XmlSerializer
。
首先通过将 XML 复制到新的 class 来创建适当的信封 classes(编辑 → 选择性粘贴 → 将 XML 粘贴为 类)
然后以此为例进行反序列化:
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(request);
using (var stream = new MemoryStream(byteArray))
{
var serializer = new XmlSerializer(typeof(Envelope));
Envelope response = (Envelope)serializer.Deserialize(stream);
Console.WriteLine(JsonConvert.SerializeObject(response));
}
尝试以下操作:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
string xml = File.ReadAllText(FILENAME);
StringReader sReader = new StringReader(xml);
XmlReader reader = XmlReader.Create(sReader);
XmlSerializer serializer = new XmlSerializer(typeof(Envelope));
Envelope envelope = (Envelope)serializer.Deserialize(reader);
}
}
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public Body Body { get; set; }
}
public class Body
{
[XmlElement(ElementName = "ProcessOneWayEvent", Namespace = "http://schemas.microsoft.com/sharepoint/remoteapp/")]
public ProcessOneWayEvent ProcessOneWayEvent { get; set; }
}
public class ProcessOneWayEvent
{
public Properties properties { get; set; }
}
public class Properties
{
public string CultureLCID { get; set; }
}
}
使用 Xml Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
string xml = File.ReadAllText(FILENAME);
XDocument doc = XDocument.Parse(xml);
string CultureLCID = (string)doc.Descendants().Where(x => x.Name.LocalName == "CultureLCID").FirstOrDefault();
}
}
}
Body
和 SPRemoteEventProperties
需要在 "http://schemas.microsoft.com/sharepoint/remoteapp/"
命名空间中:
[DataContract(Name = "Body", Namespace = "http://schemas.microsoft.com/sharepoint/remoteapp/")]
public class Body
{
[DataMember(Name = "ProcessOneWayEvent")]
public ProcessOneWayEvent ProcessOneWayEvent;
}
[DataContract(Name = "properties", Namespace = "http://schemas.microsoft.com/sharepoint/remoteapp/")]
public class SPRemoteEventProperties
{
[DataMember(Name = "CultureLCID") ]
public int CultureLCID { get; set; }
}
DataContractAttribute.Namespace
控制数据契约对象的数据成员元素序列化到的命名空间,以及数据契约对象时根元素的命名空间是根元素。由于元素 <ProcessOneWayEvent xmlns="http://schemas.microsoft.com/sharepoint/remoteapp/">
声明了一个新的默认 XML 命名空间,元素本身及其子元素都在这个命名空间中。因此,包含数据协定对象 Body
必须相应地设置其数据成员命名空间。至于 <properties xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
,i:
命名空间不是默认命名空间,因此实际上没有元素分配给此命名空间,并且 SPRemoteEventProperties
类型不应将自身分配给它。
固定 fiddle here.