简体   繁体   中英

Deserialization of JSON object with sub field as string using DataContractJsonSerializer in C#

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.

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"}}

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+", " ") + "\"");
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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