3

I am calling an API that expects my data in a format that looks like this:

{  
    "cartId":null,
    "id":"944990015513953203",
    "quantity":"3",
    "modifier":{  
        "1033306667720114200":1033308953984892900
    }
}

But I am having issues generating a c# class from that. The modifier objects first property name (1033306667720114200) is not always the same. Does anyone know how I can create a class that when deserialized will output the same json as I have shown in my example?

r3plica
  • 13,017
  • 23
  • 128
  • 290
  • possible duplicate of [How can I parse a JSON string that would cause illegal C# identifiers?](http://stackoverflow.com/questions/24536533/how-can-i-parse-a-json-string-that-would-cause-illegal-c-sharp-identifiers) – Dour High Arch Jul 20 '15 at 18:09
  • Regarding the Dictionary idea, can you have square braces around the modifier values (such that it's treated as an array) vs. the curly braces. Otherwise, the JSON feels a little awkward because it's treating a key like a property name. – Colin Jul 20 '15 at 18:13
  • I don't think the dictionary idea works because the second value is also changing. – r3plica Jul 20 '15 at 18:20
  • That's the whole point of the dictionary but it will look like [{"key", "value"}] with square braces surrounding the collection instead of {"property name", "value"} which treats it like a single instance. Will the square braces approach work for your purposes, or do you have no control over the expected JSON format? – Colin Jul 20 '15 at 18:38

3 Answers3

2

You can pack your modifier values into a dictionary.

public class MyObject
{
    public long Id {get;set;}
    public long? CartId {get;set;}
    public int Quantity {get;set;}
    public Dictionary<object, object> Modifier {get;set;}
}

EDIT

Based on comment this should be close

public class RootObject
{
    public object cartId { get; set; }
    public string id { get; set; }
    public string quantity { get; set; }
    public Modifier modifier { get; set; }
}

public class Modifier
{
    public long _1033306667720114200 { get; set; }
}
drooksy
  • 284
  • 2
  • 8
  • This didn't work for me, posting the json above to the method makes the Modifier look like {[,]} with no values. – r3plica Jul 20 '15 at 18:22
  • OIC.. "1033306667720114200" is really an object name. The solution would be that Modifier is of a type called "1033306667720114200" but that would be invalid.... I going to make a edit – drooksy Jul 20 '15 at 18:26
  • no, that won't work either. Modifier (your class) has a static name, but the Json property name changes. – r3plica Jul 20 '15 at 18:32
  • The problem is that 1033306667720114200 needs to be a class property, and class properties need to start with alpha char not numeric in C# – drooksy Jul 20 '15 at 18:33
1

The easiest and most flexible way to handle custom json format would be to implement custom JSON.Net converter. Below is example implementation that works for your json message.

First is Cart type

public class Cart
{
    public long? cartId { get; set; }
    public string id { get; set; }
    public string quantity { get; set; }
    public CartModifier modifier { get; set; }
}

[JsonConverter(typeof(CartModifierSerializer))]
public class CartModifier
{
    public CartModifier()
    {
        Values = new Dictionary<string, long>();
    }

    public Dictionary<string, long> Values { get; set; }
}

and next is custom json converter for CartModifier class

public class CartModifierSerializer : JsonConverter {
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var modifier = value as CartModifier;
        writer.WriteStartObject();
        foreach (var pair in modifier.Values)
        {
            writer.WritePropertyName(pair.Key);
            writer.WriteValue(pair.Value);
        }
        writer.WriteEndObject();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jsonObject = JObject.Load(reader);
        var properties = jsonObject.Properties().ToList();
        return new CartModifier
        {
            Values = properties.ToDictionary(x => x.Name, x => (long) x.Value)
        };
    }

    public override bool CanConvert(Type objectType)
    {
        return typeof(CartModifier).IsAssignableFrom(objectType);
    }
}

and below are example serialization/deserialization usages:

[Test]
public void TestSerialization()
{
    var cart = new Cart()
    {
        id = "944990015513953203",
        quantity = "3",
        modifier = new CartModifier()
        {
            Values =
            {
               {"1033306667720114200", 1033308953984892900}
            }
        }
    };
    Console.WriteLine(JsonConvert.SerializeObject(cart));
}

[Test]
public void TestDeseriazliation()
{
    var data = "{\"cartId\":null, \"id\":\"944990015513953203\",\"quantity\":\"3\",\"modifier\":{ \"1033306667720114200\":1033308953984892900 }}";
    var cart = JsonConvert.DeserializeObject<Cart>(data);
    Assert.AreEqual(cart.modifier.Values["1033306667720114200"], 1033308953984892900);
}
Vitaliy Tsvayer
  • 765
  • 4
  • 14
0

Use LinkedHashMap

LinkedHashMap<String, String> jsonOrderedMap = new LinkedHashMap<String, String>();

    jsonOrderedMap.put("1","red");
    jsonOrderedMap.put("2","blue");
    jsonOrderedMap.put("3","green");

    JSONObject orderedJson = new JSONObject(jsonOrderedMap);

    JSONArray jsonArray = new JSONArray(Arrays.asList(orderedJson));
Mukesh Y
  • 762
  • 6
  • 16