首页 > 解决方案 > 如果 json 包含无效标记,则 C# Newtonsoft.Json DeserializeObject

问题描述

如何使用 Newtonsoft.Json.JsonConvert.DeserializeObject 在 C# 中反序列化这个 json?问题是我不能将“事件”用作类属性,因为它是无效的令牌。

{
  "resultsPage": {
    "results": {
      "event": {
        "location": {
          "city": "London, UK",
          "lng": -0.1150322,
          "lat": 51.4650846
        },
        "uri": "http://www.....",
        "displayName": "Test",
        "id": 3037536,
        "type": "Testtype",
        "start": {
          "time": "19:30:00",
          "date": "2010-02-16",
          "datetime": "2010-02-16T19:30:00+0000"
        },
        "status": "ok"
      }
    },
    "status": "ok"
  }
}

标签: c#json.netjson-deserialization

解决方案


使用 Newtonsoft 有几种方法可以做到这一点。

JsonConvert.DeserializeObject将返回一个类型的对象JObject,这可以通过不指定类型(反序列化后进行强制转换)或指定 JObject 类型来完成。

从这里您可以访问事件,因为它只是一个键名,但您会丢失 json 的任何强类型。

var jobj = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(json);    
var _event = jobj["resultsPage"]["results"]["event"];

更进一步,您可以使用JsonConvert.DeserializeAnonymousType和指定匿名类型的定义,使用@eventEvent在 json 中存在事件的位置。访问该属性时,您需要使用@eventEvent取决于您选择的对象,并且您可以获得强类型对象的好处。

var jobj = Newtonsoft.Json.JsonConvert.DeserializeAnonymousType(json, new {
    resultsPage = new {
        results = new {
            @event = new {
                location = new {
                    city = "",
                    lng = 0.0,
                    lat = 0.0
                },
                uri = "",
                displayName = "",
                id = 0,
                type = "",
                start = new {
                    time = "",
                    date = "",
                    datetime = new DateTime()
                },
                status = ""
            }
        },
        status = ""
    }
});

var _event = jobj.resultsPage.results.@event;

接下来,您可以使用此匿名对象定义创建类并将其拆分为类,再次使用@eventorEvent它将反序列化。

var jobj = Newtonsoft.Json.JsonConvert.DeserializeObject<JsonClass>(json);
var _event = jobj.resultsPage.results.@event;

public class JsonClass
{
    public ResultsPage resultsPage { get; set; }
    public string status { get; set; }
}

public class ResultsPage
{
    public Results results { get; set; }
    public string status { get; set; }
}

public class Results
{
    public Event @event { get; set; }
}

public class Event
{
    public Location location { get; set; }
    ...
}

public class Location
{
    public string city { get; set; }
}

或者您可以查看使用属性属性将完全不同的属性名称映射到 json 键(以下是上述内容的修改摘录)。

public class Results
{
    [JsonProperty(PropertyName = "event")]
    public EventResult EventResult { get; set; }
}

public class EventResult
{
    public Location location { get; set; }
}

推荐阅读