2

I am using YamlDotNet library to serialize some objects in Yaml. I've met some problems with the serialization of Guid properties. Serialization of Guid properties generates empty brackets ( ex: {} )

See code below

Dim l As New List(Of Person)
l.Add(New Person() With {.Firstname = "MyFirstName", .Lastname = "MyLastName", .Id = Guid.NewGuid()})

Using sw As New StreamWriter("output.yaml", False)
    Dim serializer = New Serializer()
    serializer.Serialize(sw, l)
End Using

this code will output :

- Id: {}
  Firstname: MyFirstName
  Lastname: MyLastName

With the class:

Public Class Person
    Public Property Id As Guid
    Public Property Frstname As String
    Public Property Lastname As String
End Class

Am I missing something or is this an issue of the library ?

Kristofen44
  • 118
  • 1
  • 10
  • The library issue is not throwing an exception for types that are not supported in YAML. – Hans Passant Sep 17 '14 at 12:34
  • So Guid type is not supported by YamlDotNet Serialization/Deserialization ? I was expecting the library to output something like {1234564-1232132-21321321} and then this string can be easily parsed as a system.guid ... – Kristofen44 Sep 17 '14 at 13:34
  • The Guid type is not natively supported, but adding support is trivial. See my answer. – Antoine Aubry Oct 13 '14 at 22:36

1 Answers1

0

You can define a custom converter to use when you need to customize the serialization of a type. The converter needs to implement IYamlTypeConverter, and be registered on the Serializer or Deserializer. Here is an example of such a converter:

Public Class GuidConverter
    Implements IYamlTypeConverter

    Public Function Accepts(type As Type) As Boolean Implements IYamlTypeConverter.Accepts
        Return type = GetType(Guid)
    End Function

    Public Function ReadYaml(parser As IParser, type As Type) As Object Implements IYamlTypeConverter.ReadYaml
        Dim reader = New EventReader(parser)
        Dim scalar = reader.Expect(Of Scalar)()
        Return Guid.Parse(scalar.Value)
    End Function

    Public Sub WriteYaml(emitter As IEmitter, value As Object, type As Type) Implements IYamlTypeConverter.WriteYaml
        emitter.Emit(New Scalar(value.ToString()))
    End Sub
End Class

The usage is quite simple:

Dim serializer = New Serializer()
serializer.RegisterTypeConverter(New GuidConverter())
serializer.Serialize(Console.Out, New With {.id = Guid.NewGuid()})

You can see a fully working example here.

Antoine Aubry
  • 12,203
  • 10
  • 45
  • 74
  • How would deserializing work for this example? Trying to deserialize the output `id: eff34230-ed6c-4c88-aaba-6f6a177c733c` back into a `Guid` throws an exception: https://dotnetfiddle.net/exp9su – Jeff Dec 12 '14 at 19:16