dotnet/wpf · error · XamlXmlWriterException
XamlXmlWriterException(SR.ExpandPositionalParametersinTypeWi…
Error message
XamlXmlWriterException(SR.ExpandPositionalParametersinTypeWithNoDefaultConstructor)
What it means
When XamlXmlWriter expands positional parameters of a markup extension into property-element form, it must instantiate the extension type to look up constructor argument names. If the containing type's ConstructionRequiresArguments is true (no default constructor), the expansion cannot proceed, so it throws XamlXmlWriterException ExpandPositionalParametersinTypeWithNoDefaultConstructor.
Solutions
- Add a public parameterless constructor to the markup extension type
- Write the extension using explicit named property syntax instead of positional parameters so expansion is unnecessary
- Adjust the type's XAML schema/type mapping so ConstructionRequiresArguments is false (e.g. via XamlDeferLoadAttribute or constructor configuration)
Example fix
// before
class MyExt { public MyExt(string a) {...} } // no default ctor, positional args -> throws
// after
class MyExt {
public MyExt() {...}
public MyExt(string a) {...}
} Defensive patterns
Strategy: validation
Validate before calling
if (extType.ConstructionRequiresArguments) throw new InvalidOperationException($"{extType.UnderlyingType} needs a default constructor for positional-parameter expansion"); Type guard
bool CanExpandPositionalParams(XamlType t) => t == null || !t.ConstructionRequiresArguments;
Try / catch
try { writer.WriteNode(reader); }
catch (XamlXmlWriterException ex) when (ex.Message.Contains("positional")) { /* fall back to named-property syntax */ } Prevention
- Give every custom MarkupExtension a public parameterless constructor
- Avoid relying on positional constructor args in serialized XAML
- Verify ConstructionRequiresArguments via the schema context in tests
When it happens
Trigger: Writing a markup-extension object that uses positional constructor arguments (x:Arguments style) where the extension's XamlType has ConstructionRequiresArguments == true, triggering ExpandPositionalParameters state.
Common situations: Custom markup extensions without a parameterless constructor being serialized; types changed to remove their default constructor in a newer library version; serializers encountering {Extension arg=value} syntax requiring expansion.
Related errors
- ArgumentNullException(nameof(arrayType))
- ArgumentNullException(nameof(member))
- brokenRule (SR.UnexpectedToken-based parser rule error)
- IAmbientProvider
- IXamlSchemaContextProvider
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/3f8644e50f2264e4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlXmlWriter.cs:1073
}
else
{
WriteMemberAsElement(writer);
writer.WriteDeferredNamespaces(XamlNodeType.StartMember);
}
if (property == XamlLanguage.PositionalParameters)
{
// the writer is not in a state where it can write markup extensions in curly form
// so it expands the positional parameters as properties.
writer.namespaceScopes.Pop();
// but in order to expand parameters, the markup extension needs to have a default constructor
if (containingType is not null && containingType.ConstructionRequiresArguments)
{
throw new XamlXmlWriterException(SR.ExpandPositionalParametersinTypeWithNoDefaultConstructor);
}
writer.ppStateInfo.ReturnState = State;
writer.currentState = ExpandPositionalParameters.State;
}
else
{
writer.currentState = InMember.State;
}
}
public override void WriteEndObject(XamlXmlWriter writer)
{
Debug.Assert(writer.namespaceScopes.Count > 0);
Frame frame = writer.namespaceScopes.Pop();
if (frame.AllocatingNodeType != XamlNodeType.StartObject &&
frame.AllocatingNodeType != XamlNodeType.GetObject)
{View on GitHub (pinned to 81131a70a4)