将包含List <string>的Dictionary <string,object>序列化为值</string> </string,object>

时间:2013-08-22 13:50:23

标签: c# serialization

我正在使用博客中的SerializableDictionary类,我还使用了一些复杂类型来序列化。不幸的是我收到了一个错误,不知道如何解决这个问题。

有一点需要注意的是,我使用的是Mono,因为我使用的是Unity3D。我不知道这是否会使这个问题与众不同,我还没有测试.net是否也会返回此错误。

这是stacktrace的上半部分:

  

InvalidOperationException:参数对象的类型   'System.Collections.Generic.List`1 [[System.String,mscorlib,   Version = 2.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]'   不是原始的。

     

System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive   (System.String name,System.String ns,System.Object o,Boolean   xsiType)

namespace Foo
{
    class Program
    {
        static void Main(string[] args)
        {
            Foo f = new Foo();
            string result = f.Serialize();

            Console.WriteLine(result);
            Console.ReadLine();
        }
    }

    class Foo
    {
        private SerializableDictionary<string, object> dict;

        public Foo()
        {
            dict = new SerializableDictionary<string, object>();
            dict.Add("list", new List<string>() { "test1", "test2" });
        }

        public string Serialize()
        {
            XmlSerializer x = new XmlSerializer(dict.GetType(), new Type[] {typeof(List<string>)});
            StringWriter w = new StringWriter();
            x.Serialize(w, dict);
            return w.ToString();
        }
    }
}

更新
我在.NET中创建了一个测试程序,它告诉我 {“类型System.Collections.Generic.List`1 [[System.String,...]]可能不会在此上下文中使用。 “}

我已更新上面的示例代码。

1 个答案:

答案 0 :(得分:0)

首先检查在SerializableDictionary中指定值类型后是否会出现错误。

同时指定内部类型可能会有所帮助:

var x = new XmlSerializer(myobjects.GetType(), new[] { typeof(List<string>) } );

PS:您也可以查看Json.Net;)

更新1:

如果为SerializableDictionary代码指定值类型,则示例代码将起作用:

...
private SerializableDictionary<string, List<string>> dict;

public Foo()
{
    dict = new SerializableDictionary<string, List<string>>();
    dict.Add("list", new List<string>() { "test1", "test2" });
}

更新2:

“Bug”在ValueSerializer中的SerializableDictionary类中:

protected XmlSerializer ValueSerializer
{
    get
    {
        if (valueSerializer == null)
        {
            valueSerializer = new XmlSerializer(typeof(TVal));
        }
        return valueSerializer;
    }
}

如果将object设置为TVal,则XmlSerializer将无法序列化List。

更新3:

如果您不知道值类型,可以尝试在额外类型中指定所有可能的复杂类型:

protected XmlSerializer ValueSerializer
{
    get
    {
        if (valueSerializer == null)
        {
            valueSerializer = new XmlSerializer(typeof(TVal), 
                new[]
                    {
                        typeof(List<string>), 
                        typeof(List<int>)
                    });
        }
        return valueSerializer;
    }
}

或者使用像Json.NET这样的动态框架:

var dict = new Dictionary<string, object>();
dict.Add("list", new List<string>() { "test1", "test2" });

var str = JsonConvert.SerializeObject(dict);

Console.WriteLine(str);

var dict2 = JsonConvert.DeserializeObject(str, typeof(Dictionary<string, object>));