Skip to content

YamlMember Alias isn't applied when using the CamelCaseNamingConvention #228

@ghost

Description

If I ask a deserializer to use the CamelCaseNamingConvention then it appears to ignore or otherwise fail to use an Alias declared using a YamlMember attribute.

What I Expected to Happen

The CamelCaseNamingConvention should be applied to all property names.
The YamlMember Alias should then override the property names where it exists.

What Actually Happened

I get an exception saying the property can't be found despite using the YamlMember Alias.

Exception

Run-time exception (line 27): (Line: 3, Col: 5, Idx: 8) - (Line: 3, Col: 5, Idx: 8): Exception during deserialization

Stack Trace:

[System.Runtime.Serialization.SerializationException: Property 'sub_item' not found on type 'Item'.]

[YamlDotNet.Core.YamlException: (Line: 3, Col: 5, Idx: 8) - (Line: 3, Col: 5, Idx: 8): Exception during deserialization]
  at Program.Main(): line 27

Reproduction/Code

Here's a reproduction of the issue:

https://dotnetfiddle.net/ZOmLwf

using System.Collections.Generic;
using System.IO;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
					
public class Program
{
	public static void Main()
	{
		var yaml = @"
1:
    typeID: 1
    sub_item:
        name: foo
2:
    typeID: 2
    sub_item:
        name: bar
";
		
		var deserializer = new DeserializerBuilder()
			.WithNamingConvention(new CamelCaseNamingConvention())
			.Build();
		
		using (var textReader = new StringReader(yaml))
		{
			var blueprintsByID = deserializer.Deserialize<Dictionary<int, Item>>(textReader);
		}
	}
}

public class Item
{
	public int TypeID { get; set; }
	
	[YamlMember(Alias ="sub_item")]
	public SubItem SubItem { get; set; }
}

public class SubItem
{
	public string Name { get; set; }
}

And here's an example without the CamelCaseNamingConvention where it's working fine:

https://dotnetfiddle.net/pwbw7R

using System.Collections.Generic;
using System.IO;
using YamlDotNet.Serialization;
					
public class Program
{
	public static void Main()
	{
		var yaml = @"
1:
    typeID: 1
    sub_item:
        name: foo
2:
    typeID: 2
    sub_item:
        name: bar
";
		
		var deserializer = new DeserializerBuilder()
			.Build();
		
		using (var textReader = new StringReader(yaml))
		{
			var blueprintsByID = deserializer.Deserialize<Dictionary<int, Item>>(textReader);
		}
	}
}

public class Item
{
	[YamlMember(Alias ="typeID")]
	public int TypeID { get; set; }
	
	[YamlMember(Alias ="sub_item")]
	public SubItem SubItem { get; set; }
}

public class SubItem
{
	[YamlMember(Alias ="name")]
	public string Name { get; set; }
}

Workaround

And here's a workaround I found in issue: #215

https://dotnetfiddle.net/RL9Eai

using System.Collections.Generic;
using System.IO;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.TypeInspectors;
					
public class Program
{
	public static void Main()
	{
		var yaml = @"
1:
    typeID: 1
    sub_item:
        name: foo
2:
    typeID: 2
    sub_item:
        name: bar
";
		
		var deserializer = new DeserializerBuilder()
			.WithNamingConvention(new CamelCaseNamingConvention())
			// Workaround to move YamlAttributesTypeInspector
			.WithTypeInspector
			(
				inner => inner,
				s => s.InsteadOf<YamlAttributesTypeInspector>()
			)
			.WithTypeInspector
			(
				inner => new YamlAttributesTypeInspector(inner),
				s => s.Before<NamingConventionTypeInspector>()
			)
			.Build();
		
		using (var textReader = new StringReader(yaml))
		{
			var blueprintsByID = deserializer.Deserialize<Dictionary<int, Item>>(textReader);
		}
	}
}

public class Item
{
	public int TypeID { get; set; }
	
	[YamlMember(Alias ="sub_item")]
	public SubItem SubItem { get; set; }
}

public class SubItem
{
	public string Name { get; set; }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions