Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Newtonsoft反序列化Json错误_Json_F#_Json.net - Fatal编程技术网

Newtonsoft反序列化Json错误

Newtonsoft反序列化Json错误,json,f#,json.net,Json,F#,Json.net,我遇到过一个例子,Newtonsoft获取完全有效的JSON文本,但反序列化错误。我有一个包含嵌入类的对象,该类由成员Year、Month、Week和DayOfWk组成。JSON如下所示: "openDate": { "Year": 1997, "Month": 12, "Week": 5, "DayOfWk": 5 }, 但反序列化后返回的数据是Year=1、Month=1、Week=1和DayOfWk=1,而不管输入的是什么JSON 下面是代码(用F#表示,但应易于阅读

我遇到过一个例子,Newtonsoft获取完全有效的JSON文本,但反序列化错误。我有一个包含嵌入类的对象,该类由成员Year、Month、Week和DayOfWk组成。JSON如下所示:

 "openDate": {
  "Year": 1997,
  "Month": 12,
  "Week": 5,
  "DayOfWk": 5
 },
但反序列化后返回的数据是Year=1、Month=1、Week=1和DayOfWk=1,而不管输入的是什么JSON

下面是代码(用F#表示,但应易于阅读):

TradeDate是一个有问题的类——它是一个F#类,公开属性Year、Month、Week和DayOfWk。年、月和周是整数;DayOfWeek是DayOfWeek枚举。DailyAnalysis对象中的所有其他字段都返回了正确的值

如何解决这个问题

请注意,如果在反序列化对象调用中不包含该类型,它确实会获得正确的数据,但只是将其作为对象返回,并且转换为正确的类型非常困难(即,我不知道如何在F#中执行)

有人能指出我忽略的一些明显的(甚至是模糊的)东西吗,或者给我指出其他资源吗


更新:请注意,
TradeDate
的构造函数使用一个
DateTime
参数。

假设您的
TradeDate
是不可变的(通常在f#中发生),那么Json.NET可以通过找到一个参数化的构造函数来反序列化此类类型,然后通过按名称(modulo case)将构造函数参数与JSON属性匹配来调用它。将为不匹配的参数指定默认值。如果
TradeDate
实际将一个
DateTime
作为输入,您将获得所看到的行为

例如,如果我们采用这样的简化版本:

type TradeDate(date : DateTime) = 
    member this.Year = date.Year
    member this.Month = date.Month
    member this.DayOfMonth = date.Day
然后使用Json.NET对其进行双向访问,如下所示:

let t1 = new TradeDate(new DateTime(1997, 12, 25))
let json1 = JsonConvert.SerializeObject(t1)
let t2 = JsonConvert.DeserializeObject<TradeDate>(json1)
let json2 = JsonConvert.SerializeObject(t2)

printfn "\nResult after round-trip:\n%s" json2
let converter = new TradeDateConverter()
let t2 = JsonConvert.DeserializeObject<TradeDate>(json1, converter)
这正是你所看到的。演示小提琴#1

那么,你有什么选择?首先,您可以修改
TradeDate
以拥有必要的构造函数,并用标记标记它。只要应用了属性,它就可以是私有的:

type TradeDate [<JsonConstructor>] private(year : int, month : int, dayOfMonth: int) = 
    member this.Year = year
    member this.Month = month
    member this.DayOfMonth = dayOfMonth

    new(date : DateTime) = new TradeDate(date.Year, date.Month, date.Day)
并反序列化如下:

let t1 = new TradeDate(new DateTime(1997, 12, 25))
let json1 = JsonConvert.SerializeObject(t1)
let t2 = JsonConvert.DeserializeObject<TradeDate>(json1)
let json2 = JsonConvert.SerializeObject(t2)

printfn "\nResult after round-trip:\n%s" json2
let converter = new TradeDateConverter()
let t2 = JsonConvert.DeserializeObject<TradeDate>(json1, converter)
let converter=new TradeDateConverter()
让t2=JsonConvert.DeserializeObject(json1,转换器)
演示小提琴#3

注:

  • 您的问题不包括
    交易日期
    的代码,特别是在
    日期时间
    和年/月/周/周表示之间转换的代码。结果证明这有点不寻常,所以我没有把它包括在答案中;请参阅和,了解如何执行此操作

  • 有关Json.NET如何为具有多个构造函数的类型选择要调用的构造函数的详细信息,请参阅


  • 假设您的
    TradeDate
    是不可变的(通常在f#中发生),那么Json.NET能够通过查找一个参数化的构造函数来反序列化此类类型,然后通过按名称(模数大小写)将构造函数参数与Json属性匹配来调用它。将为不匹配的参数指定默认值。如果
    TradeDate
    实际将一个
    DateTime
    作为输入,您将获得所看到的行为

    例如,如果我们采用这样的简化版本:

    type TradeDate(date : DateTime) = 
        member this.Year = date.Year
        member this.Month = date.Month
        member this.DayOfMonth = date.Day
    
    然后使用Json.NET对其进行双向访问,如下所示:

    let t1 = new TradeDate(new DateTime(1997, 12, 25))
    let json1 = JsonConvert.SerializeObject(t1)
    let t2 = JsonConvert.DeserializeObject<TradeDate>(json1)
    let json2 = JsonConvert.SerializeObject(t2)
    
    printfn "\nResult after round-trip:\n%s" json2
    
    let converter = new TradeDateConverter()
    let t2 = JsonConvert.DeserializeObject<TradeDate>(json1, converter)
    
    这正是你所看到的。演示小提琴#1

    那么,你有什么选择?首先,您可以修改
    TradeDate
    以拥有必要的构造函数,并用标记标记它。只要应用了属性,它就可以是私有的:

    type TradeDate [<JsonConstructor>] private(year : int, month : int, dayOfMonth: int) = 
        member this.Year = year
        member this.Month = month
        member this.DayOfMonth = dayOfMonth
    
        new(date : DateTime) = new TradeDate(date.Year, date.Month, date.Day)
    
    并反序列化如下:

    let t1 = new TradeDate(new DateTime(1997, 12, 25))
    let json1 = JsonConvert.SerializeObject(t1)
    let t2 = JsonConvert.DeserializeObject<TradeDate>(json1)
    let json2 = JsonConvert.SerializeObject(t2)
    
    printfn "\nResult after round-trip:\n%s" json2
    
    let converter = new TradeDateConverter()
    let t2 = JsonConvert.DeserializeObject<TradeDate>(json1, converter)
    
    let converter=new TradeDateConverter()
    让t2=JsonConvert.DeserializeObject(json1,转换器)
    
    演示小提琴#3

    注:

  • 您的问题不包括
    交易日期
    的代码,特别是在
    日期时间
    和年/月/周/周表示之间转换的代码。结果证明这有点不寻常,所以我没有把它包括在答案中;请参阅和,了解如何执行此操作

  • 有关Json.NET如何为具有多个构造函数的类型选择要调用的构造函数的详细信息,请参阅


  • 您可以共享
    TradeDate
    类型吗?即a?不能用简单的示例重现,请看,我所能猜测的是
    TradeDate
    构造函数的参数名称与属性名称不匹配。Json.NET使用参数名称将构造函数参数与属性匹配,因此如果名称不一致,则会传入默认值。看见但是如果没有一个我们只能猜测.dbc-我想你的最后一点可能是答案-构造函数需要一个日期时间图,当然,Json无论如何都不需要知道这是什么。我将探索其他方法来构建它。谢谢。我现在没有时间检查,但这可能是一个迫不及待的评估问题吗?将
    letJsonText=…
    更改为
    letJsonText()=…
    您可以共享
    TradeDate
    类型吗?即a?不能用简单的示例重现,请看我能猜到的是
    TradeDate
    构造函数的参数名称与属性名称不匹配。Json.NET使用参数名称将构造函数参数与属性匹配,因此如果名称不一致,则会传入默认值。看见但是如果没有一个我们只能猜测.dbc-我想你的最后一点可能是答案-构造函数需要一个日期时间图,当然,Json无论如何都不需要知道这是什么。我将探索其他方法来构建它。谢谢。我现在没有时间检查,但这可能是一个迫不及待的评估问题吗?将
    letJsonText=…
    更改为
    letJsonText()=…