dotnet/wpf · error
SR.Format(SR.MarkupWriter_CannotSerializeGenerictype…
Error message
SR.Format(SR.MarkupWriter_CannotSerializeGenerictype, type.ToString())
What it means
MarkupWriter.VerifyTypeIsSerializable throws this InvalidOperationException when the type is generic (type.IsGenericType). XAML has no representation for constructed generic types in this writer, so it refuses to serialize them rather than emit markup that could not be parsed back.
Solutions
- Serialize the generic collection's elements individually or via a non-generic collection type.
- Define a concrete non-generic type (e.g. a class deriving from List<MyItem>) and save that.
- Use a different serializer (JSON, DataContractSerializer) that supports generics.
Example fix
// before
XamlWriter.Save(new List<string> { "a" }); // InvalidOperationException: CannotSerializeGenerictype
// after
public class StringList : List<string> { }
XamlWriter.Save(new StringList { "a" }); Defensive patterns
Strategy: validation
Validate before calling
static bool IsXamlSerializable(Type t) =>
t != null && !t.IsNested && t.IsPublic && !t.IsGenericType; Type guard
static bool IsNotGeneric(Type t) => !t.IsGenericType;
Try / catch
try { XamlWriter.Save(obj, stream); }
catch (InvalidOperationException ex) when (ex.Message.Contains("generic"))
{
// fall back to a concrete collection or custom serializer
} Prevention
- Don't pass generic collections (List<T>, Dictionary<K,V>) directly to XamlWriter.Save.
- Define concrete subclasses of generic collections for XAML scenarios.
- Validate the object graph types with a pre-check before saving.
When it happens
Trigger: Calling XamlWriter.Save / MarkupWriter.WriteItem on an instance whose type is a closed generic, e.g. List<MyItem>, KeyValuePair<string,int>, or a custom generic class. VerifyTypeIsSerializable rejects type.IsGenericType after the nested/public checks.
Common situations: Saving a List<T> or Dictionary<K,V> collection as the save root with XamlWriter.Save; serializing generic view-model or wrapper types.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- ArgumentNullException(nameof(writer))
- (no message - parameterless InvalidOperationException)
- SR.CollectionCannotContainNulls
- SR.Format(SR.DeferringLoaderNoSave…
- SR.Format(SR.MarkupWriter_CannotSerializeNestedPublictype…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/af8ff2cb4d4b0aaa.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Primitives/MarkupWriter.cs:151
/// 3) a generic type
/// </summary>
/// <param name="type">
/// The type to be checked
/// </param>
internal static void VerifyTypeIsSerializable(Type type)
{
// Check the type to make sure that it is not a nested type, that it is public, and that it is not generic
if (type.IsNestedPublic)
{
throw new InvalidOperationException( SR.Format( SR.MarkupWriter_CannotSerializeNestedPublictype, type.ToString() ));
}
if (!type.IsPublic )
{
throw new InvalidOperationException( SR.Format( SR.MarkupWriter_CannotSerializeNonPublictype, type.ToString() ));
}
if (type.IsGenericType)
{
throw new InvalidOperationException( SR.Format( SR.MarkupWriter_CannotSerializeGenerictype, type.ToString() ));
}
}
#region Internal Implementation
internal MarkupWriter(XmlWriter writer)
{
_writer = writer;
_xmlTextWriter = writer as XmlTextWriter;
}
/// <summary>
/// Dispose method
/// </summary>
public void Dispose()
{
GC.SuppressFinalize(this);
}
View on GitHub (pinned to 81131a70a4)