dotnet/wpf · error
SR.Format(SR.MarkupWriter_CannotSerializeNonPublictype…
Error message
SR.Format(SR.MarkupWriter_CannotSerializeNonPublictype, type.ToString())
What it means
MarkupWriter.VerifyTypeIsSerializable throws this InvalidOperationException when the type being serialized is not publicly visible (!type.IsPublic). The XAML serializer can only emit output for public, top-level types, since the generated markup must be resolvable back to the type. Non-public (internal, private) types cannot be round-tripped in XAML.
Solutions
- Make the type public (top-level public class).
- Expose a public wrapper/DTO type and copy the data into it before saving.
- Serialize with DataContractSerializer or another serializer that supports non-public types.
Example fix
// before
class MyData { public string Name { get; set; } } // internal
XamlWriter.Save(new MyData()); // InvalidOperationException: CannotSerializeNonPublictype
// after
public class MyData { public string Name { get; set; } }
XamlWriter.Save(new MyData()); Defensive patterns
Strategy: validation
Validate before calling
static bool IsXamlSerializable(Type t) =>
t != null && !t.IsNested && t.IsPublic && !t.IsGenericType; Type guard
static bool IsPublicTopLevel(Type t) => t.IsPublic && !t.IsNested;
Try / catch
try { XamlWriter.Save(obj, stream); }
catch (InvalidOperationException ex) when (ex.Message.Contains("non-public"))
{
// map to a public DTO and retry
} Prevention
- Apply public accessibility to all model classes intended for XAML round-trip.
- Watch for internal types in shared assemblies - a common culprit.
- Lint model assemblies for non-public types reachable from serialized object graphs.
When it happens
Trigger: Calling XamlWriter.Save / MarkupWriter.WriteItem on an object whose runtime type is internal or otherwise non-public; VerifyTypeIsSerializable checks type.IsPublic after excluding nested-public types.
Common situations: Serializing internal data/model classes (common when the model lives in a shared assembly marked internal), anonymous types, or types declared with default (internal) accessibility in C#.
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
- SR.Format(SR.MarkupWriter_CannotSerializeNestedPublictype…
- ArgumentNullException(nameof(writer))
- (no message - parameterless InvalidOperationException)
- SR.Format(SR.DeferringLoaderNoSave…
- SR.Format(SR.MarkupWriter_CannotSerializeGenerictype…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/d8e07557905d6b96.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Primitives/MarkupWriter.cs:147
/// <summary>
/// Throws an exception if the given type cannot be serialized because it is
/// 1) not public
/// 2) a nested-public
/// 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()View on GitHub (pinned to 81131a70a4)