【问题标题】:Deserialization of JSON object with sub field as string using DataContractJsonSerializer in C#使用 C# 中的 DataContractJsonSerializer 将带有子字段的 JSON 对象反序列化为字符串
【发布时间】:2015-02-02 13:45:56
【问题描述】:

这是我的 JSON:

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

这是我的 JSON 反序列化函数:

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);
    }
}

我正在尝试将其序列化为Person 对象:

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

    [DataMember]
    public string Name;

    [DataMember]
    public string Children;
}

如您所见,我不想Children 输入字典,而是按原样获取 - JSON 字符串。

目前我正在这样做:

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

我得到了异常说:

反序列化 JSONSerialization.Person 类型的对象时出错。应来自命名空间“项目”的结束元素“项目”。从命名空间“item”中找到元素“a:item”。

只是澄清一下:我不希望孩子子字段被解析。

【问题讨论】:

  • 也许它不相关,但Yossi 不是缺少结束} 吗?
  • @bali182 谢谢,这是一个错字 - 已修复。

标签: c# json deserialization


【解决方案1】:

如果您使用 JavaScriptSerializer,那么您将能够将 Children 键序列化为动态字段,并在需要时以 JSON 格式读取。

Person 对象中,尝试使用dynamic 类型而不是string 作为Children 属性。

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);
}

可以使用如下方法

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

以下将出现在控制台中

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

【讨论】:

  • 不工作,我得到的只是一个没有数据的对象。也许我错过了一些东西。可以提供代码吗?
  • 谢谢。您将 Children 对象重新序列化为 json(反序列化后)的解决方案有什么区别??
  • 如果您想获得存储在动态对象中的数据的字符串视图,那么您需要将其序列化为字符串以进行查看。 FromJavaScriptSerializer 对象比 DataContractJsonSerializer 更好地处理动态类型。
  • JavaScriptSerializer 确实更好!尤其是字典。实际上现在我正在使用Json.Net,在反序列化Person 之后,我正在重新序列化Children...
【解决方案2】:

在反序列化https://dotnetfiddle.net/GWs69U之前使用RegexChildren转为字符串(加引号,换行用\n替换)

string result = Regex.Replace(json, @"(\""Children\""\:(.|\n)*?)(\{(.|\n)*\{(.|\n)*?\}(.|\n)*?\})", (m) =>
{
    return (m.Groups[1] + "\"" + Regex.Replace(m.Groups[3].Value.Replace("\n", " "), @"\s+", " ") + "\"");
});

【讨论】:

  • 我不想这样做。我已经可以将 Children 对象重新序列化为 json(反序列化后)......
  • 在考虑了所有其他选项之后,正则表达式应该始终是最后的选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-08
  • 1970-01-01
  • 1970-01-01
  • 2016-08-07
  • 1970-01-01
  • 2013-12-31
  • 1970-01-01
相关资源
最近更新 更多