来自F#的Newtonsoft.Json调用的意外结果

Jon*_*ats 2 f# json.net

我没有从这个F#代码中获得预期的结果.我期望t作为调用JsonSchema.Parse(json)的结果包含值,但它是空的.我究竟做错了什么?

open Newtonsoft.Json
open Newtonsoft.Json.Schema

let json = """{
  "Name": "Bad Boys",
  "ReleaseDate": "1995-4-7T00:00:00",
  "Genres": [
    "Action",
    "Comedy"
  ]
}"""

[<EntryPoint>]
let main argv = 
    let t  = JsonSchema.Parse(json)  
    0 // return an integer exit code
Run Code Online (Sandbox Code Playgroud)

Mar*_*ann 9

正如John Palmer指出的那样,JsonSchema.Parse解析一个JSON 模式,但是从您的问题来看,它看起来好像要解析一个普通的JSON .这有可能JsonConvert.DeserializeObject:

let t = JsonConvert.DeserializeObject json
Run Code Online (Sandbox Code Playgroud)

但是,签名DeserializeObject是要返回的obj,因此这并不特别有助于您访问这些值.为此,您必须将返回值强制转换为JObject:

let t = (JsonConvert.DeserializeObject json) :?> Newtonsoft.Json.Linq.JObject
let name = t.Value<string> "Name"
Run Code Online (Sandbox Code Playgroud)

Json.NET旨在利用C#的dynamic关键字,但其完全相同的内容并未构建到F#中.但是,您可以通过FSharp.Dynamic获得类似的语法:

open EkonBenefits.FSharp.Dynamic

let t = JsonConvert.DeserializeObject json
let name = t?Name
Run Code Online (Sandbox Code Playgroud)

注意?之前Name.请记住,JSON区分大小写.

现在,name仍然不是字符串,而是一个JValue对象,但你可以通过调用ToString()它来获取字符串值,但你也可以使用JValue's Value属性,如果值是数字而不是字符串,这可以很方便:

let jsonWithNumber = """{ "number" : 42 }"""
let t = JsonConvert.DeserializeObject jsonWithNumber
let actual = t?number?Value
Assert.Equal(42L, actual)
Run Code Online (Sandbox Code Playgroud)