SharpYaml 3 is a breaking-change release aligned with modern .NET serialization patterns.
net8.0, net10.0, and netstandard2.0.Old:
var serializer = new Serializer(new SerializerSettings());
var yaml = serializer.Serialize(value);
var model = serializer.Deserialize<MyType>(yaml);
New:
var options = new YamlSerializerOptions();
var yaml = YamlSerializer.Serialize(value, options);
var model = YamlSerializer.Deserialize<MyType>(yaml, options);
The following legacy APIs are no longer public in v3:
SerializerSerializerSettingsSerializerContextIYamlSerializable / IYamlSerializableFactoryUse these replacements:
YamlMemberAttribute -> YamlPropertyNameAttribute and/or YamlPropertyOrderAttributeYamlIgnoreAttribute -> YamlIgnoreAttribute (kept)YamlIncludeAttribute or JsonIncludeAttributeJsonPolymorphicAttribute, JsonDerivedTypeAttributeYamlPolymorphicAttribute, YamlDerivedTypeAttributeRemoved legacy attributes:
YamlMemberAttributeYamlTagAttributeYamlStyleAttributeYamlRemapAttributev3 supports key System.Text.Json.Serialization attributes directly for member mapping:
YAML-specific attributes take precedence when both are present.
Reflection fallback is available by default and can be disabled:
AppContext.SetSwitch("SharpYaml.YamlSerializer.IsReflectionEnabledByDefault", false);
When disabled, POCO/object mapping requires metadata via YamlSerializerOptions.TypeInfoResolver (typically from a YamlSerializerContext).
Built-in primitives and untyped containers remain supported without reflection.
Create a context class and declare serializable roots with YamlSerializableAttribute:
using SharpYaml.Serialization;
[YamlSerializable(typeof(MyType))]
internal partial class MyYamlContext : YamlSerializerContext
{
}
Then consume typed metadata:
var context = MyYamlContext.Default;
var yaml = YamlSerializer.Serialize(value, context.MyType);
var model = YamlSerializer.Deserialize(yaml, context.MyType);
YamlSyntaxTree) for lossless roundtrip and source span tooling.YamlSerializer maps to .NET objects and does not preserve formatting/comments.Most SerializerSettings switches from v2 were removed because v3 follows the YamlSerializerOptions/YamlSerializerContext model and aligns with System.Text.Json behavior where practical.
| v2 setting | v3 equivalent | Notes |
|---|---|---|
NamingConvention = new CamelCaseNamingConvention() |
PropertyNamingPolicy = JsonNamingPolicy.CamelCase |
Use System.Text.Json.JsonNamingPolicy for CLR property names, and DictionaryKeyPolicy for dictionary keys. |
IgnoreUnmatchedProperties = true |
default behavior | SharpYaml v3 skips unmatched YAML members by default, matching System.Text.Json. |
IgnoreUnmatchedProperties = false |
UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow |
Use the options-level setting or [JsonUnmappedMemberHandling(JsonUnmappedMemberHandling.Disallow)] on a specific type to fail on unknown members. |
EmitTags = false |
default behavior | v3 does not emit tags for ordinary object serialization unless they are required for polymorphism or explicitly written by a converter. |
ResetAlias = true |
default behavior | v3 does not preserve object identity unless ReferenceHandling = YamlReferenceHandling.Preserve is enabled. Serializer reuse does not carry aliases between operations. |
If a type has YamlExtensionDataAttribute or JsonExtensionDataAttribute, unmatched YAML members are captured there instead of being rejected.
using SharpYaml;
using System.Text.Json.Serialization;
var options = new YamlSerializerOptions
{
UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow,
};
using System.Collections.Generic;
using System.Text.Json.Serialization;
using SharpYaml.Serialization;
[JsonUnmappedMemberHandling(JsonUnmappedMemberHandling.Disallow)]
public sealed class MyModel
{
public string Name { get; set; } = string.Empty;
[YamlExtensionData]
public Dictionary<string, object?> Extra { get; set; } = new();
}
In the example above, unknown YAML members are still stored in Extra; extension data takes precedence over UnmappedMemberHandling.