F# Serialization of Record types

后端 未结 4 1106
南旧
南旧 2021-02-04 08:42

I know how to serialize in F# using mutable objects, but is there a way to serialize/deserialize using record types using either XmlSerializer or the DataContractSerializer? loo

4条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-04 09:33

    The sample code for reading data from Freebase by Jomo Fisher uses DataContractJsonSerializer to load data into immutable F# records. The declaration of the record that he uses looks like this:

    []
    type Result<'TResult> = { // '
        []
        Code:string
        []
        Result:'TResult // '
        []
        Message:string }
    

    The key point here is that the the DataMember attribute is attached to the underlying field that's actually used to store the data and not to the read-only property that the F# compiler generates (using the field: modifier on the attribute).

    I'm not 100% sure if this is going to work with other types of serialization (probably not), but it may be a useful pointer to start with...

    EDIT I'm not sure if I'm missing something here, but the following basic example works fine for me:

    module Demo
    
    #r "System.Runtime.Serialization.dll"
    
    open System.IO  
    open System.Text  
    open System.Xml 
    open System.Runtime.Serialization
    
    type Test = 
      { Result : string[]
        Title : string }
    
    do
      let sb = new StringBuilder()
      let value = { Result = [| "Hello"; "World" |]; Title = "Hacking" }
      let xmlSerializer = DataContractSerializer(typeof); 
      xmlSerializer.WriteObject(new XmlTextWriter(new StringWriter(sb)), value)
      let sr = sb.ToString()
      printfn "%A" sr
    
      let xmlSerializer = DataContractSerializer(typeof); 
      let reader = new XmlTextReader(new StringReader(sr))
      let obj = xmlSerializer.ReadObject(reader) :?> Test
      printfn "Reading: %A" obj
    

    EDIT 2 If you want to generate cleaner XML then you can add attributes like this:

    [] 
    type Test = 
      { [] 
        [, ElementName = "string")>] 
        Result : string[]
        [] 
        Title : string }
    

提交回复
热议问题