YamlDotNet - Validating during deserialization

CSharp · Console

/Program.cs

// By manipulating the list of node deserializers,
// it is easy to add behavior to the deserializer.
// This example shows how to validate the objects as they are deserialized.

using System;
using System.IO;
using System.Linq;
using System.ComponentModel.DataAnnotations;
using YamlDotNet.Core;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NodeDeserializers;

// First, we'll implement a new INodeDeserializer
// that will decorate another INodeDeserializer with validation:
public class ValidatingNodeDeserializer : INodeDeserializer
{
    private readonly INodeDeserializer _nodeDeserializer;

    public ValidatingNodeDeserializer(INodeDeserializer nodeDeserializer)
    {
        _nodeDeserializer = nodeDeserializer;
    }

    public bool Deserialize(EventReader reader, Type expectedType,
        Func<EventReader, Type, object> nestedObjectDeserializer,
        out object value)
    {
        if (_nodeDeserializer.Deserialize(reader, expectedType,
            nestedObjectDeserializer, out value))
        {
            var context = new ValidationContext(value, null, null);
            Validator.ValidateObject(value, context, true);
            return true;
        }
        return false;
    }
}

public class Program
{
	public static void Main()
	{
		// Then we wrap the existing ObjectNodeDeserializer
		// with our ValidatingNodeDeserializer:
		
		
		var deserializer = new Deserializer();

		var objectDeserializer = deserializer.NodeDeserializers
			.Select((d, i) => new {
				Deserializer = d as ObjectNodeDeserializer,
				Index = i
			})
			.First(d => d.Deserializer != null);
		
		deserializer.NodeDeserializers[objectDeserializer.Index] =
			new ValidatingNodeDeserializer(objectDeserializer.Deserializer);
		
		// This will fail with a validation exception
		deserializer.Deserialize<Data>(new StringReader(@"Name: ~"));
	}
}

public class Data
{
	[Required]
	public string Name { get; set; }
}
;