3

Here is my JSON:

{
    "Name": "Eli",
    "Age": 4,
    "Children": {
        "Moshe": {
            "Age": 6,
            "Characteristics": "Nice;Good;"
        },
        "Yossi": {
            "Age": 3,
            "Characteristics": "Hero;Brave"
        }
    }
}

Here is my JSON deserialization function:

public static object FromJSON<T>(string json) 
{
    using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(json)))
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
        return serializer.ReadObject(stream);
    }
}

I'm trying to serialize it to Person object:

[DataContract]
public class Person
{
    [DataMember]
    public int Age;

    [DataMember]
    public string Name;

    [DataMember]
    public string Children;
}

As you can see, I do not want to get Children into dictionary but to get it as is - JSON string.

Currently I'm doing it like this:

Person p = (Person)Extensions.FromJSON<Person>(output);

And I'm getting exception saying:

There was an error deserializing the object of type JSONSerialization.Person. End element 'item' from namespace 'item' expected. Found element 'a:item' from namespace 'item'.

Just to clarify: I do not want the children sub field to be parsed.

Nikolay Kostov
  • 16,433
  • 23
  • 85
  • 123
Eli
  • 4,576
  • 1
  • 27
  • 39

2 Answers2

0

If you use the JavaScriptSerializer then you will be able to serialize the Children key into a dynamic field and read it in JSON format if required.

In the Person object try and use the dynamic type instead of string for the Children property.

public static T FromJavaScriptSerializer<T>(string json)
    {
        var serializer = new JavaScriptSerializer();
        return serializer.Deserialize<T>(json);
    }


public static string ToStringOutput(object dynamicField)
{
    var serializer = new JavaScriptSerializer();
    return serializer.Serialize(dynamicField);
}

You can use the methods as follows

var person = FromJavaScriptSerializer<Person>(output);
Console.WriteLine(ToStringOutput(person.Children));

Following will appear in console

{"Moshe":{"Age":6,"Characteristics":"Nice;Good;"},"Yossi":{"Age":3,"Characteristics":"Hero;Brave"}}

Kevin Brady
  • 1,684
  • 17
  • 30
  • Not working, I'm getting just an object with no data. Maybe I'm missing something. Can you provide code? – Eli Feb 02 '15 at 14:18
  • Thanks. Whats the difference between your solution to just re-serialize the Children object to json (after de-serializing)?? – Eli Feb 03 '15 at 09:55
  • 1
    If you want to get a string view of the data stored in the dynamic object then you will need to serialize it to a string to view it. The FromJavaScriptSerializer object handles dynamic types better than DataContractJsonSerializer. – Kevin Brady Feb 03 '15 at 11:02
  • `JavaScriptSerializer` is better indeed! Especially with dictionaries. Actually now I'm using `Json.Net`, and after de-serializing `Person` I'm re-serializing `Children`... – Eli Feb 03 '15 at 13:04
-1

Use Regex to convert Children to string (add quotes, replace new lines with \n) before the deserialization https://dotnetfiddle.net/GWs69U

string result = Regex.Replace(json, @"(\""Children\""\:(.|\n)*?)(\{(.|\n)*\{(.|\n)*?\}(.|\n)*?\})", (m) =>
{
    return (m.Groups[1] + "\"" + Regex.Replace(m.Groups[3].Value.Replace("\n", " "), @"\s+", " ") + "\"");
});
Alexander Shutau
  • 2,660
  • 22
  • 32
  • 1
    I'm preferring not to do so. I already could just re-serialize the `Children` object to json (after deserializing) instead.. – Eli Feb 02 '15 at 14:40
  • Regex should always be a last ditch option, after all other options have been considered. – mason Feb 02 '15 at 19:41