【问题标题】:XML DataContractDeserialization HELP needed需要 XML DataContractDeserialization 帮助
【发布时间】:2012-01-30 05:17:56
【问题描述】:

我有以下 XML:

<?xml version="1.0" ?>
<Responses>
    <ResponseList>
      <Response type="XXX">
        <Foo>YYYY</Foo>
        <Bar>ZZZZ</Bar>
      </Response>
    </ResponseList>
</Responses>

我的类应该是什么样子才能将字符串反序列化为对象(我正在使用 DataContractSerializer)

[DataContract(Namespace = "")]
[Serializable]
public class Responses : DataContainer
{
    [DataMember]
    public ResponseCollection ResponseList { get; set; }
}

[Serializable]
public class Response : DataContainer 
{
    [DataMember]
    public string Foo { get; set; }
    [DataMember]
    public string Bar { get; set; }
}

[Serializable]
public class ResponseCollection : List<Response>
{
}

[编辑] 我实际上能够让它与 DataContractSerializer 一起工作......我的目标是利用 DataContractSerializer 将 XML 字符串(响应)反序列化为对象,并且我得到了两个属性(foo 和 bar)的 NULL。

[Serializable]
[DataContract(Namespace = "")]
public class Responses : DataContainer
{
    [DataMember(Name = "ResponseList")]
    public Response[] Response { get; set; }
}

[Serializable]
[DataContract(Namespace = "")]
public class Response : DataContainer
{
    [DataMember(Order = 0)]
    public string Foo { get; set; }
    [DataMember(Order = 1)]
    public string Bar { get; set; }
}

【问题讨论】:

  • 过去遇到这样的问题时,我已经构建了一个尽可能匹配xml定义的类,创建一个实例并用给定的测试数据填充它,然后序列化它。将结果与给定的 xml 输入进行比较并进行调整,直到它通过您的测试。然后,您应该能够反序列化到该类中。我也很想知道是否有更简单的方法。
  • 你不能用DataContractSerializer做你想做的事。它不使用属性。
  • @John Saunders - 实际上,DataContractSerializer 确实使用属性,如问题中的示例代码所示。请参阅DataMemberAttributeDataContractAttributeDataContractSerializer
  • @Nathan:我的意思是 XML 属性。
  • @John Saunders - 啊。我误解了。你见过lordzoltan.blogspot.com/2010/09/… 吗?不一定漂亮,但看起来您实际上可以将 xml 属性支持破解到其中。 (虽然我自己没有测试过)

标签: c# xml serialization collections datacontractserializer


【解决方案1】:

(此答案早于澄清需要 DataContractSerializer 的编辑)

如果我正确理解了这个例子,那么如下。注意:其他属性没有害处,但 XmlSerializer 没有使用 - 我只展示了 XmlSerializer 使用的那些。

[XmlRoot("Responses")]
public class TxTNotifyResponse : DataContainer
{
    [XmlArray("ResponseList")]
    [XmlArrayItem("Response")]
    public MsgResponseCollection MsgResponseList { get; set; }
}

public class MsgResponse : DataContainer 
{
    [XmlElement("Foo")]
    public string Status { get; set; }
    [XmlElement("Bar")]
    public string MessageId { get; set; }
}

public class MsgResponseCollection : List<MsgResponse>
{
}

如果这不起作用(而且我还没有测试过),请尝试使用单独的 DTO 模型。最简单的方法是将数据放入 XML 文件(例如 your.xml),然后使用(在命令提示符下):

xsd.exe your.xml
xsd.exe your.xsd /classes

哪个会写你的.cs

【讨论】:

  • 这是一个很好的回应,但我认为我在使用 XML 序列化程序发布时犯了错误。我有一个 XML 字符串并使用 DataContractSerializer,它的工作原理如下... public T ReadObject(string objectString) { var memoryStream = new MemoryStream(_encoding.GetBytes(objectString)); var reader = XmlDictionaryReader.CreateTextReader(memoryStream, new XmlDictionaryReaderQuotas()); var serializer = new DataContractSerializer(typeof(T)); var obj = (T)serializer.ReadObject(reader, true); reader.Close();返回对象; }
  • @Todd - 我不再清楚你的问题到底是什么。您评论中的代码未包含在您的问题中。但是,您的代码显示您正在调用 DataContractSerializer 的反序列化方法 (`ReadObject(...)')。这会给你不正确的结果吗?例外?您寻求帮助的具体问题是什么?
  • @Todd DataContractSerializer 不允许对 XML 进行同样的细粒度控制。我的建议:如果 XML 布局很重要:使用 XmlSerializer。
  • @MarcGravell - 我永远不会序列化回 XML,所以布局在这里不是什么大问题。我只是想要一种很好的方法来解析 XML 格式的 HTTP 响应......有人有更好的建议吗?
  • @Todd 布局在反序列化时同样重要
猜你喜欢
  • 2017-10-02
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
相关资源
最近更新 更多