C# 将对象数组序列化为JSON
我有一个类型,它是字典的包装器——基本上是一个键/值存储。我想将这种类型的对象数组序列化为JSON。我对JSON和JSON.NET(newtonsoft.JSON)非常陌生 我的类型有一个名为-ToJson的方法,该方法将其字典序列化为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.
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