无法将类型反序列化为JToken

时间:2017-11-01 18:57:01

标签: c# json f# json.net

我无法反序列化我的JSON的Tags属性:

{
    "posts": [
        {
            "ID": 7096,
            "title": "Backwards Pipe Operator",
            "URL": "https://bizmonger.wordpress.com/2017/10/26/backwards-pipe-operator/",
            "tags": {
                "F#": {
                    "ID": 6012,
                    "name": "F#"
                      }
                    }
        }
     ]  
}

从上面的JSON我提供了以下类型:

type Post = { 
    title: string
    URL:   string
    Tags:  JToken seq // Used to refer to the string instead of the property type
}

type Response = { posts: Post list }

尝试反序列化 Post 值的 Tags 属性时遇到异常:

 let settings = JsonSerializerSettings()
 settings.MissingMemberHandling <- MissingMemberHandling.Ignore
 let result = JsonConvert.DeserializeObject<Response>(json, settings)
  

发生了Newtonsoft.Json.JsonSerializationException   HResult = 0x80131500 Message =无法反序列化当前的JSON   对象(例如{“name”:“value”})进入类型   'System.Collections.Generic.IEnumerable`1 [Newtonsoft.Json.Linq.JToken]'   因为该类型需要一个JSON数组(例如[1,2,3])来反序列化   正确。要修复此错误,请将JSON更改为JSON数组   (例如[1,2,3])或更改反序列化类型以使其正常   .NET类型(例如,不是整数的基本类型,不是集合   类似于数组或List的类型,可以从JSON反序列化   宾语。 JsonObjectAttribute也可以添加到类型中以强制它   从JSON对象反序列化。路径'post [0] .tags.F#',第1行,   位置1582.来源=
  StackTrace:at   Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader   reader,Type objectType,JsonContract契约,JsonProperty成员,   JsonContainerContract containerContract,JsonProperty containerMember,   Object existingValue)...

附录

这是JSON URL

try let url =        String.Format(ArticlesUrl, user.AccessId)
    let response =   client.GetAsync(url) |> Async.AwaitTask 
                                          |> Async.RunSynchronously
    if response.IsSuccessStatusCode
    then let json =     response.Content.ReadAsStringAsync() |> Async.AwaitTask 
                                                             |> Async.RunSynchronously
         let settings = JsonSerializerSettings()
         settings.MissingMemberHandling <- MissingMemberHandling.Ignore

         let result = JsonConvert.DeserializeObject<Response>(json, settings);

1 个答案:

答案 0 :(得分:2)

图书馆非常明确地告诉你错误:Cannot deserialize ... JSON object ... into type 'JToken seq' because the type requires a JSON array to deserialize correctly

Seq是一个东西的序列(即列表,数组,枚举)。它对应于JSON数组,而不是JSON对象。

要在不事先知道属性名称的情况下反序列化JSON对象,请使用IDictionary

type Post = { 
    title: string 
    URL: string 
    Tags: IDictionary<string, JToken>
}

此外,如果您确实知道每个标记的形状(ID + name),那么您可以做得更好:

type Tag = { ID: string; name: string }

type Post = { 
    title: string 
    URL: string 
    Tags: IDictionary<string, Tag>
}