dotnet/wpf · error · XamlXmlWriterException

SR.ExpandPositionalParametersinTypeWithNoDefaultConstructor

Error message

SR.ExpandPositionalParametersinTypeWithNoDefaultConstructor

What it means

Same failure mode as the positional-parameter expansion guard but reached from the property-expansion path: when expanding a markup extension written with property syntax (or implicit members) XamlXmlWriter needs to instantiate the extension type, and if containingType.ConstructionRequiresArguments is true (no default constructor) it throws XamlXmlWriterException ExpandPositionalParametersinTypeWithNoDefaultConstructor at this site.

Solutions

  1. Add a public parameterless constructor to the markup extension class
  2. Serialize the extension with attribute/explicit property syntax that avoids the expansion path
  3. Provide a custom XamlValueConverter/type mapping so the writer does not need to instantiate the type

Example fix

// before
public class MyExt : MarkupExtension { public MyExt(int n) {...} } // throws on expansion
// after
public class MyExt : MarkupExtension {
  public MyExt() {}
  public MyExt(int n) {...}
}
Defensive patterns

Strategy: validation

Validate before calling

if (extType != null && extType.ConstructionRequiresArguments && expansionNeeded) throw new InvalidOperationException("Markup extension must have a default constructor for expansion");

Type guard

bool CanExpandMarkupExtension(XamlType t) => t == null || !t.ConstructionRequiresArguments;

Try / catch

try { writer.WriteNode(reader); }
catch (XamlXmlWriterException ex) when (ex.Message.Contains("DefaultConstructor")) { /* serialize with named properties instead */ }

Prevention

When it happens

Trigger: Writing a markup extension with expansion required (property-element expansion path at line ~1181) where the containing markup-extension XamlType lacks a default constructor (ConstructionRequiresArguments true).

Common situations: Custom MarkupExtension classes without parameterless constructors; refactors that added required constructor arguments; serialization of extensions used in templates/styles that forces expansion.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/9b256f884c8c85a6. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlXmlWriter.cs:1181

                writer.namespaceScopes.Push(new Frame
                {
                    AllocatingNodeType = XamlNodeType.StartMember,
                    Type = writer.namespaceScopes.Peek().Type,
                    Member = property
                });

                XamlType containingType = writer.namespaceScopes.Peek().Type;
                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 properties, 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 if (IsImplicit(property))
                {
                    // Stop trying attributes

                    writer.WriteDeferredNamespaces(XamlNodeType.StartObject);
                    writer.currentState = InMember.State;
                }
                else if (property == containingType.ContentProperty)
                {
                    writer.currentState = TryContentPropertyInTryAttributesState.State;
                }
                else if (property.IsDirective && (property.Type is not null && (property.Type.IsCollection || property.Type.IsDictionary)))
                {

View on GitHub (pinned to 81131a70a4)