使用Json.net解析嵌套的JSON

3
我有JSON反序列化的问题,以下是我的JSON:
{
    "_id" : ObjectId("56bc28c436b252c406a67f17"),
    "empname": "dhiraj",
    "empcode": "123a",
    "level": {
        "levelID": 3,
        "levelDescription": "manager",
        "levelCode": "mg"
    },
    "Address": [
        {
            "Home": {
                "streetname": "Home",
                "city": "bbb",
                "state": "aaa"
            }
        },
        {
            "Office": {
                "streetname": "ofc",
                "city": "ccc",
                "state": "ddd"
            }
        }
    ]
}

对于上述JSON,对象类别如下:

public class Employee
{
    public ObjectId _id { get; private set; }
    public string empname { get; set; }
    public string empcode { get; set; }
    public List<Level> level { get; set; }
    public List<Address> Address { get; set; }
}

public class level
{
    public string levelID { get; set; }
    public string levelDescription { get; set; }
    public string levelCode { get; set; }
}
public class Address
{
    public List<Home> Home { get; set; }
    public List<office> Office { get; set; }
}
public class Home
{
    public string streetname { get; set; }
    public string city { get; set; }
    public string state { get; set; }
}
public class office
{
    public string streetname { get; set; }
    public string city { get; set; }
    public string state { get; set; }
}

我尝试使用以下代码进行反序列化

Employee empobj = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Employee>>(jsonData);

但是遇到了以下错误:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

如何解决这个问题?这个json结果是来自于mongodb c#查询的吗?


嗯,你给出的JSON不是一个List<Employee> - 它根本就不是一个数组。它只是一个单独的Employee对象。所以使用DeserializeObject<Employee>来解析它。天哪,考虑到你将其赋值给一个Employee变量,我甚至不指望你给出的代码能够编译通过... - Jon Skeet
但是你提供的JSON不是一个数组,而只是一个单独的对象。这就是反序列化程序抱怨的原因。如果在开头添加一个额外的[和结尾处添加一个],我认为它会正常工作...但是“一个元素的数组”和“一个元素”之间存在着巨大的区别。 - Jon Skeet
@jon:我尝试在JSON的开头和结尾添加[ ],但仍然出现相同的错误,我认为我的类结构存在问题。 - user
你可以在地址、家庭和办公室上遇到同样的问题——你的JSON指定了一个对象,但是你的类声明了一个列表。而且,ObjectId 部分的JSON无效,不够清晰。 - Jon Skeet
这仍然是无效的JSON。你不能在JSON中指定这样的值。但是基本上,你的“level”属性(而不是地址,抱歉)应该只是一个“level”,而不是一个“List<level>”,你的“Home”和“Office”属性应该只是“Home”或“Office”,而不是列表。(最好根本不要分开成类...)我会写一个答案... - Jon Skeet
显示剩余3条评论
1个回答

3

这里有几个问题:

  • 你提供的代码无法编译,因为你指定了一个名为level的类,但在使用时使用了Level
  • 你试图反序列化一个List<Employee>,但是你的JSON只指定了单个Employee对象;这与包含单个对象的对象数组不同
  • 你的JSON是无效的——ObjectId("56bc28c436b252c406a67f17")在JSON中根本不是有效值。也许Json.NET对这种奇怪情况有一些支持,但最好还是使用有效的JSON
  • 你的Address类为Home属性指定了一个List<Home>,为Office属性做同样的操作,但是JSON仅指定了一个对象值,而不是一个数组。对于level属性也是如此。

另外,你的HomeOffice分别有单独的类,这是相当糟糕的,命名规则混乱。地址的JSON结构远非理想,但我猜你无法解决这个问题。

我不能真正解决ObjectId的问题,但我会按以下方式构建类:

public class Employee
{
    [JsonProperty("_id")]
    public ObjectId Id { get; private set; }

    [JsonProperty("empname")]
    public string Name { get; set; }

    [JsonProperty("empcode")]
    public string Code { get; set; }

    [JsonProperty("level")]
    public Level Level { get; set; }

    [JsonProperty("Address")]
    public List<Address> Addresses { get; set; }
}

public class Level
{
    [JsonProperty("levelID")]
    public string Id { get; set; }

    [JsonProperty("levelDescription")]
    public string Description { get; set; }

    [JsonProperty("levelCode")]
    public string Code { get; set; }
}

// This structure is unfortunate, but imposed by the JSON
public class Address
{
    [JsonProperty("Home")]
    public StreetAddress Home { get; set; }

    [JsonProperty("Office")]
    public StreetAddress Office { get; set; }
}

public class StreetAddress
{
    [JsonProperty("streetname")]
    public string StreetName { get; set; }

    [JsonProperty("city")]
    public string City { get; set; }

    [JsonProperty("state")]
    public string State { get; set; }
}

除了ObjectId,它将使用以下方式解析给定的JSON:
var employee = JsonConvert.DeserializeObject<Employee>(json);

这个Address类中是否需要StreetAddress属性呢?希望你在回答时没有遗漏它。 - user
@dhiraj:抱歉,是的 - 不确定发生了什么。现在请看一下。 - Jon Skeet
感谢类结构对我有帮助,因为我是mongodb和c#的新手,一直在尝试将mongodb文档映射到c#类中,并且不需要进行反序列化,因为这已经由c# mongo驱动程序和bson驱动程序处理了。再次感谢。 - user

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接