- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 507
Closed

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
Labels
No labels
