【问题标题】:C# KeyValuePair deserialization of a list as "value" fieldC# KeyValuePair 将列表反序列化为“值”字段
【发布时间】:2016-12-27 13:39:09
【问题描述】:

我有一个用 XML 序列化的 KeyValuePair 对象,对于每个键,都有一个值列表,如下所示:

<WritableKeyValuePairOfKeyContraenteArrayOfAddress>
   <key>
      <KeyContaente>123456</KeyContaente>
   </key>
   <value>
      <Address>Maple road 12</Address>
   </value>
   <value>
      <Address>Oak street 71</Address>
   </value>
</WritableKeyValuePairOfKeyContraenteArrayOfAddress>

问题是:当我反序列化时,对象的值只包含一个元素:第一个元素(“枫叶路 12”)。为什么会这样?

编辑: 序列化:

public static string Serializza<T>(T objectToSerialize)
    {
        using (MemoryStream memStm = new MemoryStream())
        {
            var serializer = new DataContractSerializer(typeof(T));
            serializer.WriteObject(memStm, objectToSerialize);

            memStm.Seek(0, SeekOrigin.Begin);

            using (var streamReader = new StreamReader(memStm))
            {
                string result = streamReader.ReadToEnd();
                return result;
            }
        }
    }

反序列化:

    private static T Deserializza<T>(string xmlString)
    {
        if (xmlString.Length > 0)
        {
            try
            {
                var serializer = new DataContractSerializer(typeof(T));
                using (System.IO.MemoryStream memStm = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(xmlString)))
                {
                    return (T)serializer.ReadObject(memStm);
                }
            }
            catch
            {
                return default(T);
            }
        }
        else
            return default(T);
    }

KeyValuePair 就像一个字典:

[Serializable, StructLayout(LayoutKind.Sequential)]
public class WritableKeyValuePair<TKey, TValue> : IWritableKeyValuePair
{
    private TKey key;
    private TValue value;

    public WritableKeyValuePair() { }
    public WritableKeyValuePair(TKey key, TValue value)
    {
        this.key = key;
        this.value = value;
    }

    public override string ToString()
    {
        return WKVPUtils<TKey, TValue>.ToString(key, value);
    }

    ////[XmlProcessDeep()]
    public TValue Value
    {
        get { return this.value; }
        set { this.value = value; }
    }

    public TKey Key
    {
        get { return this.key; }
        set { this.key = value; }
    }

    internal static class WKVPUtils<TKey, TValue>
    {
        public static string ToString(TKey Key, TValue Value)
        {
            StringBuilder builder1 = new StringBuilder();
            builder1.Append('[');
            if (Key != null)
                builder1.Append(Key.ToString());
            builder1.Append(", ");
            if (Value != null)
                builder1.Append(Value.ToString());
            builder1.Append(']');
            return builder1.ToString();
        }
    }
}

【问题讨论】:

  • 向我们展示代码。你究竟是如何序列化的?你究竟是如何反序列化的?你说的这个 KeyValuePair 是什么?
  • 查看操作中的编辑
  • 仅供参考:visual-studio 标记为:“除非您对 Visual Studio 有特定问题,否则不要使用此标记,而不仅仅是编码问题”。我已经删除了标签。

标签: c# .net c#-4.0


【解决方案1】:

(代表 OP 发布)

解决了。我必须按如下方式编辑 XML 结构:

<WritableKeyValuePairOfKeyContraenteArrayOfAddress>
   <key>
      <KeyContaente>123456</KeyContaente>
   </key>
   <value>
      <Address>Maple road 12</Address>
      <Address>Oak street 71</Address>
   </value>
</WritableKeyValuePairOfKeyContraenteArrayOfAddress>

在我为每个&lt;Address&gt; 标签设置&lt;value&gt; 标签之前,现在只有一个打开和关闭&lt;value&gt; 标签,包含多个&lt;Address&gt; 标签。

【讨论】:

    【解决方案2】:

    试试这个

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                string xml =
                    "<Root>" +
                    "<WritableKeyValuePairOfKeyContraenteArrayOfAddress>" +
                       "<key>" +
                          "<KeyContaente>123456</KeyContaente>" +
                       "</key>" +
                       "<value>" +
                          "<Address>Maple road 12</Address>" +
                          "<Address>Oak street 71</Address>" +
                       "</value>" +
                    "</WritableKeyValuePairOfKeyContraenteArrayOfAddress>" +
                    "</Root>";
    
                XElement elements = XElement.Parse(xml);
    
                Dictionary<string, List<string>> dict = elements.Descendants("WritableKeyValuePairOfKeyContraenteArrayOfAddress").Select(x => new
                {
                    key = (string)x.Descendants("KeyContaente").FirstOrDefault(),
                    values = x.Descendants("Address").Select(y => (string)y).ToList()
                }).GroupBy(x => x.key, y => y.values)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());
            }
        }
    }
    

    【讨论】:

    • 我无法将“值”转换为目标类型:values = x.Descendants("RecapitoPolizza").Select(y => (Allianz.Anagrafe.AnagraficaQuietanzamentoDTO.RecapitoPolizza)y)。 ToList()
    • 错误:无法将类型“XElement”转换为“RecapitoPolizza”
    • 标签 RecapitoPolizza 不在发布的 xml 代码中。不知道你从我发布的代码中改变了什么。我需要查看更多 xml 文件以确定您更改我发布的代码的原因。
    • 'RecapitoPolizza' 是'地址'
    • 您必须在 xml 中使用准确的标签名称。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多