C# 使用DataContractSerializer反序列化WCF中的XML
我正在向WCF REST服务发布一个XML文档。我能够使用DataContractSerializer获取要解析的元素,但无法提取属性。我尝试了其他SO问题的几种方法,但要么无法获得要解析的属性,要么无法生成正确的对象。例如,我的代码目前只解析一个字段数据,字段列表为空。提供的代码是我的最新尝试 我在我的MLW类上实现了IXmlSerializable,并且能够解析出属性,但是我在孩子们身上遇到了麻烦。因为我使用的是XMlReader,所以我得到了意想不到的结果,因为子类中的读取器对于它们在文档中的位置没有任何上下文。其他示例只显示了容器元素中可以解析为列表的一种数据类型,但我有几个FieldData元素,它们是Job元素的同级 有没有更好的方法来实现这一点 这是我的MLW课程C# 使用DataContractSerializer反序列化WCF中的XML,c#,.net,xml,wcf,C#,.net,Xml,Wcf,我正在向WCF REST服务发布一个XML文档。我能够使用DataContractSerializer获取要解析的元素,但无法提取属性。我尝试了其他SO问题的几种方法,但要么无法获得要解析的属性,要么无法生成正确的对象。例如,我的代码目前只解析一个字段数据,字段列表为空。提供的代码是我的最新尝试 我在我的MLW类上实现了IXmlSerializable,并且能够解析出属性,但是我在孩子们身上遇到了麻烦。因为我使用的是XMlReader,所以我得到了意想不到的结果,因为子类中的读取器对于它们在文档
[XmlRoot(ElementName = "MLW", Namespace = "")]
public class MLW : IXmlSerializable
{
public string Cmd { get; set; }
public string OrgId { get; set; }
public string Id { get; set; }
public string LTStamp { get; set; }
public string TStamp { get; set; }
public string DevId { get; set; }
public string RouteId { get; set; }
public string TruckId { get; set; }
public string SType { get; set; }
public string LocationAddress { get; set; }
public string LocationCity { get; set; }
public string LocationState { get; set; }
public string LocationPostalCode { get; set; }
public string StopId { get; set; }
public string LocationKey { get; set; }
public List<FieldData> FieldDatas = new List<FieldData>();
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
XmlSerializer serializer = new XmlSerializer(typeof(FieldData));
Cmd = reader.GetAttribute("Cmd");
OrgId = reader.GetAttribute("OrgId");
Id = reader.GetAttribute("Id");
LTStamp = reader.GetAttribute("LTStamp");
TStamp = reader.GetAttribute("TStamp");
DevId = reader.GetAttribute("DevId");
RouteId = reader.GetAttribute("RouteId");
TruckId = reader.GetAttribute("TruckId");
SType = reader.GetAttribute("SType");
LocationAddress = reader.GetAttribute("LocationAddress");
LocationCity = reader.GetAttribute("LocationCity");
LocationState = reader.GetAttribute("LocationState");
LocationPostalCode = reader.GetAttribute("LocationPostalCode");
StopId = reader.GetAttribute("StopId");
LocationKey = reader.GetAttribute("LocationKey");
while (reader.Read())
{
if (reader.IsStartElement())
{
switch (reader.Name.ToString())
{
case "FieldData":
FieldDatas.Add((FieldData)serializer.Deserialize(reader));
break;
}
}
}
}
public void WriteXml(XmlWriter writer){ }
}
这就是XML
<?xml version="1.0" encoding="UTF-8"?>
<MLW Cmd="8" OrgId="999999944" Id="8888" LTStamp="2012-01-31T16:33:18" TStamp="2012-01-31T20:33:18" DevId="f7d4e3efbc9c555ef45f0a920d505c0c" RouteId="R1101-1" TruckId="50242" SType="3" LocationAddress="790 REDWOOD SQ,UNIT 3" LocationCity="OAKVILLE" LocationState="ON" LocationPostalCode="L6L6N3" StopId="43225" LocationKey="43225">
<FieldData LCode="1" OwnerId="43225">
<Field FId="1962" Name="Capture Signature?" Value="Signed">
<Child FId="1963" Name="Received By" Value="JM" />
<Child FId="1964" Name="Signature" Key="Signature" Value="abc123" />
</Field>
<Field FId="1543" Name="Disclaimer" Value="See Terms and Conditions at www.midlandtransport.com No claims will accepted unless noted on this device." />
<RField>
<Field FId="1538" Name="Delays" Value="Waiting For Door">
<Child FId="1862" Name="Time Spent" Value="15 min" />
</Field>
<Field FId="1538" Name="Delays" Value="Waiting to get Unloaded">
<Child FId="1862" Name="Time Spent" Value="30 min" />
</Field>
</RField>
</FieldData>
<FieldData LCode="2" OwnerId="Order1100-2">
<RField>
<Field FId="1533" Name="Accessorials" Value="Tail Gate" />
<Field FId="1533" Name="Accessorials" Value="2 Man Service" />
</RField>
<Field FId="2106" Name="Driver Collect?" Value="True">
<Child FId="2109" Name="Driver Coll Amt" Value="32" />
</Field>
<Field FId="2065" Name="COD?" Value="True">
<Child FId="2066" Name="COD Amt" Value="45" />
</Field>
</FieldData>
<FieldData LCode="2" OwnerId="Order1100-4">
<RField>
<Field FId="1533" Name="Accessorials" Value="Tail Gate" />
<Field FId="1533" Name="Accessorials" Value="2 Man Service" />
</RField>
<RField>
<Field FId="1516" Name="OSD Reason" Value="Damaged and Kept">
<Child FId="1957" Name="Pieces" Value="55" />
<Child FId="1960" Name="Units" Value="Roll" />
</Field>
<Field FId="1516" Name="OSD Reason" Value="Shortage (Concealed)">
<Child FId="1957" Name="Pieces" Value="5" />
<Child FId="1960" Name="Units" Value="Skid" />
</Field>
<Field FId="1516" Name="OSD Reason" Value="Refusal">
<Child FId="1957" Name="Pieces" Value="500" />
<Child FId="1960" Name="Units" Value="Unit" />
</Field>
</RField>
<Field FId="2106" Name="Driver Collect?" Value="False" />
<Field FId="2065" Name="COD?" Value="False" />
</FieldData>
<Job JobId="Order1100-2" JType="3" Status="4" DispatchStopId="396934">
<Item ItemId="1" Status="4" Key="" Name="" />
</Job>
<Job JobId="Order1100-4" JType="3" Status="4" DispatchStopId="396936">
<Item ItemId="1" Status="4" Key="" Name="" />
</Job>
</MLW>
更新
我可以通过向服务接口中的端点定义添加[XmlSerializerFormat]并使用Visual Studio的“将XML粘贴为类”功能为您构建XML所需的类来实现它 您应该尝试将属性显式标记为元素或属性 如 看起来你做的事情比这里需要的还要多。(我这样说是因为我不知道你项目的大背景)
您应该能够创建一些POCO,让datacontract序列化程序完成它的工作。只需根据需要使用[XmlRoot]、[XmlElement]、[XmlAttribute]和[XmlArray]来提示序列化程序。我通常不会处理所有这些readxml方法,因为这基本上相当于手动反序列化,这并没有真正节省我任何时间。我会将此标记为答案,但我还必须做一些其他事情。
public class Field : IXmlSerializable
{
public string FId { get; set; }
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
FId = reader.GetAttribute("FId");
}
public void WriteXml(XmlWriter writer) { }
}
<?xml version="1.0" encoding="UTF-8"?>
<MLW Cmd="8" OrgId="999999944" Id="8888" LTStamp="2012-01-31T16:33:18" TStamp="2012-01-31T20:33:18" DevId="f7d4e3efbc9c555ef45f0a920d505c0c" RouteId="R1101-1" TruckId="50242" SType="3" LocationAddress="790 REDWOOD SQ,UNIT 3" LocationCity="OAKVILLE" LocationState="ON" LocationPostalCode="L6L6N3" StopId="43225" LocationKey="43225">
<FieldData LCode="1" OwnerId="43225">
<Field FId="1962" Name="Capture Signature?" Value="Signed">
<Child FId="1963" Name="Received By" Value="JM" />
<Child FId="1964" Name="Signature" Key="Signature" Value="abc123" />
</Field>
<Field FId="1543" Name="Disclaimer" Value="See Terms and Conditions at www.midlandtransport.com No claims will accepted unless noted on this device." />
<RField>
<Field FId="1538" Name="Delays" Value="Waiting For Door">
<Child FId="1862" Name="Time Spent" Value="15 min" />
</Field>
<Field FId="1538" Name="Delays" Value="Waiting to get Unloaded">
<Child FId="1862" Name="Time Spent" Value="30 min" />
</Field>
</RField>
</FieldData>
<FieldData LCode="2" OwnerId="Order1100-2">
<RField>
<Field FId="1533" Name="Accessorials" Value="Tail Gate" />
<Field FId="1533" Name="Accessorials" Value="2 Man Service" />
</RField>
<Field FId="2106" Name="Driver Collect?" Value="True">
<Child FId="2109" Name="Driver Coll Amt" Value="32" />
</Field>
<Field FId="2065" Name="COD?" Value="True">
<Child FId="2066" Name="COD Amt" Value="45" />
</Field>
</FieldData>
<FieldData LCode="2" OwnerId="Order1100-4">
<RField>
<Field FId="1533" Name="Accessorials" Value="Tail Gate" />
<Field FId="1533" Name="Accessorials" Value="2 Man Service" />
</RField>
<RField>
<Field FId="1516" Name="OSD Reason" Value="Damaged and Kept">
<Child FId="1957" Name="Pieces" Value="55" />
<Child FId="1960" Name="Units" Value="Roll" />
</Field>
<Field FId="1516" Name="OSD Reason" Value="Shortage (Concealed)">
<Child FId="1957" Name="Pieces" Value="5" />
<Child FId="1960" Name="Units" Value="Skid" />
</Field>
<Field FId="1516" Name="OSD Reason" Value="Refusal">
<Child FId="1957" Name="Pieces" Value="500" />
<Child FId="1960" Name="Units" Value="Unit" />
</Field>
</RField>
<Field FId="2106" Name="Driver Collect?" Value="False" />
<Field FId="2065" Name="COD?" Value="False" />
</FieldData>
<Job JobId="Order1100-2" JType="3" Status="4" DispatchStopId="396934">
<Item ItemId="1" Status="4" Key="" Name="" />
</Job>
<Job JobId="Order1100-4" JType="3" Status="4" DispatchStopId="396936">
<Item ItemId="1" Status="4" Key="" Name="" />
</Job>
</MLW>
[XmlAttribute(AttributeName = "Cmd")]
public string Cmd { get; set; }
public string OrgId { get; set; }
public string Id { get; set; }