Search code examples
c#jsondatacontractserializer

Serialize a Dictionary<string,Type> and remove key/value from JSON string


I have following code snippet in which I am serializing an object into JSON. The code is working fine, but I want to remove Key and Value keywords from the JSON string.

Current output:

{
   "Description":"test",
   "RoomTypes":[
      {
         "Key":"A",
         "Value":{
            "Name":"Delux"
         }
      },
      {
         "Key":"B",
         "Value":{
            "Name":"Non delux"
         }
      }
   ],
   "Url":"http:\/\/test.com"
}

Desired output:

{
   "Description":"test",
   "RoomTypes":[
      {
         "A":{
            "Name":"Delux"
         }
      },
      {
         "B":{
            "Name":"Non delux"
         }
      }
   ],
   "Url":"http:\/\/test.com"
}

My test code:

namespace ConsoleApplication1
{
    [DataContract]
    public class Room
    {
        [DataMember]
        public string Url { get; set; }
        [DataMember]
        public string Description { get; set; }
        [DataMember]
        public Dictionary<string, RoomTypes> RoomTypes { get; set; }
    }

    [DataContract]
    public class RoomTypes
    {
        [DataMember]
        public string Name { get; set; }
    }

    public class Test
    {
        static void Main(string[] args)
        {
            Room room = new Room { Url = "http://test.com", Description="test" };
            RoomTypes roomType1 = new RoomTypes() { Name = "Delux" };
            RoomTypes roomType2 = new RoomTypes() { Name = "Non delux" };
            room.RoomTypes = new Dictionary<string, RoomTypes>();
            room.RoomTypes["A"] = roomType1;
            room.RoomTypes["B"] = roomType2;

            DataContractJsonSerializer dataContractSer = 
                   new DataContractJsonSerializer(typeof(Room));
            StringBuilder sb = new StringBuilder();
            MemoryStream ms = new MemoryStream();
            dataContractSer.WriteObject(ms, room);
            var result = Encoding.UTF8.GetString(ms.ToArray());
            Console.WriteLine(result);
        }
    }
}

Is there a way to do this?


Solution

  • It's not fun, but try this:

    [Test]
    public void Json()
    {
             var input = @"{
       ""Description"":""test"",
       ""RoomTypes"":[
          {
             ""Key"":""A"",
             ""Value"":{
                ""Name"":""Delux""
             }
          },
          {
             ""Key"":""B"",
             ""Value"":{
                ""Name"":""Non delux""
             }
          }
       ],
       ""Url"":""http:\/\/test.com""
    }";
    
        var temp = JsonConvert.DeserializeObject<Temp>(input);
        var transform = new Transform
            {
                Description = temp.Description,
                Url = temp.Url,
                RoomTypes = new List<IDictionary<string, Temp.NameObj>>()
            };
    
        foreach (var group in temp.RoomTypes)
        {
            var dic = new Dictionary<string, Temp.NameObj> {{@group.Key, @group.Value}};
            transform.RoomTypes.Add(dic);
        }
    
        Console.WriteLine(JsonConvert.SerializeObject(transform));
    }
    
    public class Transform
    {
        public string Description { get; set; }
        public IList<IDictionary<string, Temp.NameObj>> RoomTypes { get; set; }
        public string Url { get; set; }
    }
    
    
    public class Temp
    {
        public string Description { get; set; }
        public IList<GroupObj> RoomTypes { get; set; }
        public string Url { get; set; }
    
        public class GroupObj
        {
            public string Key { get; set; }
            public NameObj Value { get; set; }
        }
    
        public class NameObj
        {
            public string Name { get; set; }
        }
    }    
    

    The idea is to use Json.Net's dictionary serialization to achieve the structure you want.