简体   繁体   English

在C#中将通用集合转换为JSON

[英]Convert Generic Collection to JSON in C#

I'm facing a scenario while adding data into a collection. 在将数据添加到集合中时,我正面临一个场景。 I need to add some data into a collection and then convert into json in a required format. 我需要将一些数据添加到集合中,然后以所需的格式转换为json。

The problem is i'm not getting my required json output, only dictionary collection giving me my required output but dictionary doesn't allow duplicate keys in it, and i need to add duplicate data. 问题是我没有得到我所需的json输出,只有字典集合给我我所需的输出但字典不允许重复键,我需要添加重复数据。

I've tried different collection but unable to get required out put. 我尝试了不同的收藏品,但无法获得所需的收费。

Please look at the following code snippets and suggest me a proper solution. 请查看以下代码段并建议我一个合适的解决方案。

//with distinct emails
var dict = new Dictionary<string, object>();
dict.Add("user1@company.com", new { id = 1, first = "FirstName", last = "LastName" });
dict.Add("user2@company.com", new { id = 2, first = "FirstName", last = "LastName" });
dict.Add("user3@company.com", new { id = 3, first = "FirstName", last = "LastName" });
dict.Add("user4@company.com", new { id = 4, first = "FirstName", last = "LastName" });
string dictJson = new JavaScriptSerializer().Serialize(dict);
//json result (requires output)
//{"user1@company.com":{"id":1,"first":"FirstName","last":"LastName"},"user2@company.com":{"id":2,"first":"FirstName","last":"LastName"},"user3@company.com":{"id":3,"first":"FirstName","last":"LastName"},"user4@company.com":{"id":4,"first":"FirstName","last":"LastName"}}

//Snippet - I: with duplicate emails
var list = new List<KeyValuePair<string, object>>();
list.Add(new KeyValuePair<string, object>("user1@company.com", new { id = 1, first = "FirstName", last = "LastName" }));
list.Add(new KeyValuePair<string, object>("user1@company.com", new { id = 2, first = "FirstName", last = "LastName" }));
list.Add(new KeyValuePair<string, object>("user2@company.com", new { id = 3, first = "FirstName", last = "LastName" }));
list.Add(new KeyValuePair<string, object>("user2@company.com", new { id = 4, first = "FirstName", last = "LastName" }));
string listJson = new JavaScriptSerializer().Serialize(list);
//json result
//[{"Key":"user1@company.com","Value":{"id":1,"first":"FirstName","last":"LastName"}},{"Key":"user1@company.com","Value":{"id":2,"first":"FirstName","last":"LastName"}},{"Key":"user2@company.com","Value":{"id":3,"first":"FirstName","last":"LastName"}},{"Key":"user2@company.com","Value":{"id":4,"first":"FirstName","last":"LastName"}}]

//Snippet - II: with duplicate emails
var tupleList = new List<Tuple<string, CustomClass>>();
tupleList.Add(Tuple.Create("user1@company.com", new CustomClass { id = 1, first = "FirstName", last = "LastName" }));
tupleList.Add(Tuple.Create("user1@company.com", new CustomClass { id = 2, first = "FirstName", last = "LastName" }));
tupleList.Add(Tuple.Create("user2@company.com", new CustomClass { id = 3, first = "FirstName", last = "LastName" }));
tupleList.Add(Tuple.Create("user2@company.com", new CustomClass { id = 4, first = "FirstName", last = "LastName" }));
string tupleListJson = new JavaScriptSerializer().Serialize(tupleList);
//json result
//[{"Item1":"user1@company.com","Item2":{"id":1,"first":"FirstName","last":"LastName"}},{"Item1":"user1@company.com","Item2":{"id":2,"first":"FirstName","last":"LastName"}},{"Item1":"user2@company.com","Item2":{"id":3,"first":"FirstName","last":"LastName"}},{"Item1":"user2@company.com","Item2":{"id":4,"first":"FirstName","last":"LastName"}}]

//Snippet - III: with duplicate emails
var genericList = new List<MainClass>();
genericList.Add(new MainClass { email = "user1@company.com", details = new CustomClass { id = 1, first = "FirstName", last = "LastName" } });
genericList.Add(new MainClass { email = "user1@company.com", details = new CustomClass { id = 2, first = "FirstName", last = "LastName" } });
genericList.Add(new MainClass { email = "user2@company.com", details = new CustomClass { id = 3, first = "FirstName", last = "LastName" } });
genericList.Add(new MainClass { email = "user2@company.com", details = new CustomClass { id = 4, first = "FirstName", last = "LastName" } });
string genericListJson = new JavaScriptSerializer().Serialize(genericList);
//json result
//[{"email":"user1@company.com","details":{"id":1,"first":"FirstName","last":"LastName"}},{"email":"user1@company.com","details":{"id":2,"first":"FirstName","last":"LastName"}},{"email":"user2@company.com","details":{"id":3,"first":"FirstName","last":"LastName"}},{"email":"user2@company.com","details":{"id":4,"first":"FirstName","last":"LastName"}}]

I dont want key name in json result. 我不想要json结果中的密钥名称。 I just need email as key and object as its value. 我只需要将电子邮件作为关键字和对象作为其价值。 Like this 像这样

{"user1@company.com":{"id":1,"first":"FirstName","last":"LastName"}}

First, use a List<KeyValuePair<string, object>> since you need to allow duplicates. 首先,使用List<KeyValuePair<string, object>>因为您需要允许重复。

var list = new List<KeyValuePair<string, object>>();
list.Add(new KeyValuePair<string, object>("foo", new { id = 1, first = "FirstName", last = "LastName" }));
list.Add(new KeyValuePair<string, object>("foo", new { id = 1, first = "FirstName", last = "LastName" }));
list.Add(new KeyValuePair<string, object>("foo", new { id = 1, first = "FirstName", last = "LastName" }));

Serialize with JsonConvert . 使用JsonConvert进行序列化。

JsonSerializerSettings settings = new JsonSerializerSettings { Converters = new[] { new MyConverter() } };
string json = JsonConvert.SerializeObject(list, settings);

And use a custom converter inspired from this answer : 并使用这个答案启发自定义转换器

public class MyConverter : JsonConverter
{

    public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
    {
        List<KeyValuePair<string, object>> list = value as List<KeyValuePair<string, object>>;
        writer.WriteStartArray();
        foreach (var item in list)
        {
            writer.WriteStartObject();
            writer.WritePropertyName(item.Key);
            // Needed because of the dynamic object.
            var jsonValue = JsonConvert.SerializeObject(item.Value);
            writer.WriteValue(jsonValue);
            writer.WriteEndObject();
        }
        writer.WriteEndArray();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(List<KeyValuePair<string, object>>);
    }
}

Output: 输出:

[
    {"foo":"{\"id\":1,\"first\":\"FirstName\",\"last\":\"LastName\"}"},
    {"foo":"{\"id\":1,\"first\":\"FirstName\",\"last\":\"LastName\"}"},
    {"foo":"{\"id\":1,\"first\":\"FirstName\",\"last\":\"LastName\"}"}
]

在此输入图像描述

In order to that you need to store your data in list of dictionary. 为此,您需要将数据存储在字典列表中。 It is not perfect solution but you can get your desired output in this way 它不是完美的解决方案,但您可以通过这种方式获得所需的输出

class ValueHolder {
public string id { get; set; }
public string otherProp { get; set; }
}


var dic1 = new Dictionary<string, ValueHolder>();
dic1.Add("b@b.com", new ValueHolder { id = "1", otherProp = "Lorem" });
dic1.Add("a@a.com", new ValueHolder { id = "1", otherProp = "Lorem" });

var dic2 = new Dictionary<string, ValueHolder>();
dic2.Add("b@b.com", new ValueHolder { id = "2", otherProp = "Lorem" });
dic2.Add("a@a.com", new ValueHolder { id = "2", otherProp = "Lorem" });

var listOfDic = new List<Dictionary<string, ValueHolder>> { dic1, dic2 };
var result = JsonConvert.SerializeObject(listOfDic, Formatting.Indented);
[
  {
    "b@b.com": {
      "id": "1",
      "otherProp": "lorem"
    },
    "a@a.com": {
      "id": "1",
      "otherProp": "lorem"
    }
  },
  {
    "b@b.com": {
      "id": "2",
      "otherProp": "lorem"
    },
    "a@a.com": {
      "id": "2",
      "otherProp": "lorem"
    }
  }
]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM