【问题标题】:Deserialize option<'a>反序列化选项<'a>
【发布时间】:2012-02-12 20:41:49
【问题描述】:

当尝试反序列化从 JSON 字符串返回的 Header option 类型的记录成员时,我收到以下异常:

数据合约类型 'Microsoft.FSharp.Core.FSharpOption`1[[MyWeb.Controllers.Header, MyWeb.Controllers,版本=0.0.0.0,文化=中性, PublicKeyToken=null]]' 无法反序列化,因为需要 未找到数据成员“值”。

我正在序列化/反序列化 Message 记录:

[<DataContract>]
type Header = 
    { [<DataMember>] mutable ID          : int
      [<DataMember>] mutable Description : string }

[<DataContract>]
type Message =
    { [<DataMember>] mutable ID          : int
      [<DataMember>] mutable Header      : Header option
      [<DataMember>] mutable SenderID    : string
      [<DataMember>] mutable ReceiverID  : string }

我用来反序列化 JSON 的代码:

let deserializeJson<'a> (s:string) =   
    use ms = new MemoryStream(ASCIIEncoding.ASCII.GetBytes s)   
    let serialize = DataContractJsonSerializer(typeof<'a>)   
    serialize.ReadObject ms :?> 'a 

以及实际的原始 JSON 结果:

"Message":
{
    "ID":13,
    "Header": { "Value":{"ID":21,"Description":"some"}},
    "SenderID":"312345332423",
    "ReceiverID":"16564543423" 
}

问题:如何反序列化'a option?

更新

ASP.NET MVC 默认使用JavaScriptSerializer 序列化对象,而我使用DataContractJsonSerializer 反序列化。

由于某种原因,DataContractJsonSerializer 似乎无法读取 JSON 字符串,除非该选项的 Value 属性为小写字母(正如 @svick 所指出的那样)。一个肮脏的解决方法是在返回的 JSON 字符串中将“Value”替换为“value”,但我选择了 Roberts 的建议。

【问题讨论】:

  • JSON 字符串长什么样子?
  • 你如何序列化它?显而易见的方式对我来说是个例外。此外,在运行deserializeJson 时,我得到了同样的异常(抱怨没有设置访问器)。
  • @svick,我将 ASP.NET MVC 用于 REST API。 API 是用 F# 编写的。我使用Controller 类中的Json (msdn.microsoft.com/en-us/library/dd504936.aspx) 方法对记录进行序列化。要回答您以前的问题,那么客户端的记录成员应该是可变的以便设置(请参阅更新)。
  • 嗯,在每一侧使用不同的序列化程序可能是问题所在。如果您将 JSON 更改为具有 value(小写),那么它适用于我。

标签: serialization f# datacontract


【解决方案1】:

如果您要跳到使用 json.net(又名 Newtonsoft.Json)而不是 .NET 框架附带的 json 序列化程序,那么您可以使用我构建的 option serializer 让我更有效地工作与ravendb。应该只是向序列化程序注册转换并调用反序列化的问题。

【讨论】:

    猜你喜欢
    • 2014-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    相关资源
    最近更新 更多