Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将对象数组序列化为JSON_C#_.net_Json_Json.net - Fatal编程技术网

C# 将对象数组序列化为JSON

C# 将对象数组序列化为JSON,c#,.net,json,json.net,C#,.net,Json,Json.net,我有一个类型,它是字典的包装器——基本上是一个键/值存储。我想将这种类型的对象数组序列化为JSON。我对JSON和JSON.NET(newtonsoft.JSON)非常陌生 我的类型有一个名为-ToJson的方法,该方法将其字典序列化为json,如下所示 public string ToJson() { return JsonConvert.SerializeObject(this.values); } 然后我尝试序列化这些对象的数组 var json = JsonConvert.

我有一个类型,它是字典的包装器——基本上是一个键/值存储。我想将这种类型的对象数组序列化为JSON。我对JSON和JSON.NET(newtonsoft.JSON)非常陌生

我的类型有一个名为-ToJson的方法,该方法将其字典序列化为json,如下所示

public string ToJson()
{
  return JsonConvert.SerializeObject(this.values);
}    
然后我尝试序列化这些对象的数组

var json = JsonConvert.SerializeObject(objectArray)
当然,这不起作用,因为数组中的每个对象都是序列化的,我不知道如何将序列化过程指向每个对象的“ToJson”方法

如果传入一个Dictionary对象数组,我可以让它完全按照我想要的方式工作

也许我缺少了一些序列化属性

编辑:


在阅读了更多的文档之后,我尝试了一种更短的方法(在考虑JsonConverter方法之前)——使用“JsonPropertyAttribute”。将它应用到privatedictionary成员几乎完成了这项工作,只是我还序列化了成员名,这是我不想要的。是否可以通过使用JsonPropertyAttribute来序列化成员值而不是成员名称?

尝试对任何类型的对象进行此操作。这是我使用的通用JSON序列化程序代码

public class JsonUtils
{
    #region
    public static string JsonSerializer<T>(T t)
    {
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
        MemoryStream ms = new MemoryStream();
        ser.WriteObject(ms, t);
        string jsonString = Encoding.UTF8.GetString(ms.ToArray());
        ms.Close();
        return jsonString;
    }
    /// <summary>
    /// JSON Deserialization
    /// </summary>
    public static T JsonDeserialize<T>(string jsonString)
    {
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
        T obj = (T)ser.ReadObject(ms);
        return obj;
    }
    #endregion
}
公共类JsonUtils
{
#区域
公共静态字符串JsonSerializer(T)
{
DataContractJsonSerializer ser=新的DataContractJsonSerializer(类型(T));
MemoryStream ms=新的MemoryStream();
ser.WriteObject(ms,t);
字符串jsonString=Encoding.UTF8.GetString(ms.ToArray());
Close女士();
返回jsonString;
}
/// 
///JSON反序列化
/// 
公共静态T JsonDeserialize(字符串jsonString)
{
DataContractJsonSerializer ser=新的DataContractJsonSerializer(类型(T));
MemoryStream ms=新的MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T obj=(T)ser.ReadObject(ms);
返回obj;
}
#端区
}

为了序列化包装器类,使其内部字典出现在JSON中,就好像包装器不在那里一样,您需要一个自定义的
JsonConverter
JsonConverter
可以直接控制特定类的序列化和/或反序列化内容

下面是一个适用于您的案例的转换器。因为除了有一个名为
values
的字段来保存字典之外,您没有提供关于包装器类的任何详细信息,所以我使用反射来访问它。如果您的类具有直接操作字典的公共方法,那么如果愿意,您可以将转换器更改为使用这些方法。代码如下:

class DictionaryWrapperConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(MyWrapper));
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        MyWrapper wrapper = (MyWrapper)value;
        FieldInfo field = typeof(MyWrapper).GetField("values", BindingFlags.NonPublic | BindingFlags.Instance);
        JObject jo = JObject.FromObject(field.GetValue(wrapper));
        jo.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        MyWrapper wrapper = new MyWrapper();
        FieldInfo field = typeof(MyWrapper).GetField("values", BindingFlags.NonPublic | BindingFlags.Instance);
        field.SetValue(wrapper, jo.ToObject(field.FieldType));
        return wrapper;
    }
}
要将自定义转换器绑定到包装类,可以向类定义添加
[JsonConverter]
属性:

[JsonConverter(typeof(DictionaryWrapperConverter))]
class MyWrapper : IEnumerable
{
    Dictionary<string, string> values = new Dictionary<string, string>();

    public void Add(string key, string value)
    {
        values.Add(key, value);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return values.GetEnumerator();
    }
}

在调用
ToJson()
之前,在数组上调用
jsonvert.SerializeObject
。净结果将是相同的。@Always在回答后续问题时学习:不,没有办法使用
[JsonProperty]
属性来消除属性名。这就是为什么您需要转换器。这并不能解决问题中提出的问题。
class Program
{
    static void Main(string[] args)
    {
        MyWrapper wrapper = new MyWrapper();
        wrapper.Add("foo", "bar");
        wrapper.Add("fizz", "bang");

        // serialize single wrapper instance
        string json = JsonConvert.SerializeObject(wrapper, Formatting.Indented);

        Console.WriteLine(json);
        Console.WriteLine();

        // deserialize single wrapper instance
        wrapper = JsonConvert.DeserializeObject<MyWrapper>(json);

        foreach (KeyValuePair<string, string> kvp in wrapper)
        {
            Console.WriteLine(kvp.Key + "=" + kvp.Value);
        }
        Console.WriteLine();
        Console.WriteLine("----------\n");

        MyWrapper wrapper2 = new MyWrapper();
        wrapper2.Add("a", "1");
        wrapper2.Add("b", "2");
        wrapper2.Add("c", "3");

        List<MyWrapper> list = new List<MyWrapper> { wrapper, wrapper2 };

        // serialize list of wrappers
        json = JsonConvert.SerializeObject(list, Formatting.Indented);

        Console.WriteLine(json);
        Console.WriteLine();

        // deserialize list of wrappers
        list = JsonConvert.DeserializeObject<List<MyWrapper>>(json);

        foreach (MyWrapper w in list)
        {
            foreach (KeyValuePair<string, string> kvp in w)
            {
                Console.WriteLine(kvp.Key + "=" + kvp.Value);
            }
            Console.WriteLine();
        }
    }
}
{
  "foo": "bar",
  "fizz": "bang"
}

foo=bar
fizz=bang

----------

[
  {
    "foo": "bar",
    "fizz": "bang"
  },
  {
    "a": "1",
    "b": "2",
    "c": "3"
  }
]

foo=bar
fizz=bang

a=1
b=2
c=3