DapperLib/Dapper · error · InvalidOperationException

A parameterless default constructor or one matching signatur

Error message

A parameterless default constructor or one matching signature {proposedTypes} is required for {type.FullName} materialization

What it means

Thrown during deserializer IL generation when `typeMap.FindConstructor(names, types)` returns null — i.e. the target type has neither a parameterless constructor nor a constructor whose parameters match the result-set column names/types. Dapper needs a way to instantiate the type; with no usable ctor it cannot proceed, so it reports the expected signature in the message and throws InvalidOperationException.

Source

Thrown at Dapper/SqlMapper.cs:3528

                        }
                    }

                    il.Emit(OpCodes.Newobj, explicitConstr);
                    il.Emit(OpCodes.Stloc, returnValueLocal);
                    supportInitialize = typeof(ISupportInitialize).IsAssignableFrom(type);
                    if (supportInitialize)
                    {
                        il.Emit(OpCodes.Ldloc, returnValueLocal);
                        il.EmitCall(OpCodes.Callvirt, typeof(ISupportInitialize).GetMethod(nameof(ISupportInitialize.BeginInit))!, null);
                    }
                }
                else
                {
                    var ctor = typeMap.FindConstructor(names, types);
                    if (ctor is null)
                    {
                        string proposedTypes = "(" + string.Join(", ", types.Select((t, i) => t.FullName + " " + names[i]).ToArray()) + ")";
                        throw new InvalidOperationException($"A parameterless default constructor or one matching signature {proposedTypes} is required for {type.FullName} materialization");
                    }

                    if (ctor.GetParameters().Length == 0)
                    {
                        il.Emit(OpCodes.Newobj, ctor);
                        il.Emit(OpCodes.Stloc, returnValueLocal);
                        supportInitialize = typeof(ISupportInitialize).IsAssignableFrom(type);
                        if (supportInitialize)
                        {
                            il.Emit(OpCodes.Ldloc, returnValueLocal);
                            il.EmitCall(OpCodes.Callvirt, typeof(ISupportInitialize).GetMethod(nameof(ISupportInitialize.BeginInit))!, null);
                        }
                    }
                    else
                    {
                        specializedConstructor = ctor;
                    }
                }

View on GitHub (pinned to 72a54c475f)

Solutions

  1. Add a parameterless constructor to the type (properties will then be set by name).
  2. Align constructor parameter names with the result column names (case-insensitive), or alias columns in SQL to match the ctor params.
  3. Use a CustomPropertyTypeMap / SetTypeMap to specify the exact constructor to use.
  4. Map onto a concrete class with settable properties instead of an interface or a ctor-only struct whose names mismatch.

Example fix

// before
public class User { public User(int userId) {} public string Name {get;set;} }
// select returns columns: Id, Name  -> 'userId' ctor does not match 'Id'
// after: add parameterless ctor or rename
public class User { public User() {} public int Id {get;set;} public string Name {get;set;} }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the target type has a parameterless ctor or a ctor matching column names.
var hasDefaultCtor = typeof(T).GetConstructor(Type.EmptyTypes) is not null;
if (!hasDefaultCtor) throw new InvalidOperationException(typeof(T).Name + " needs a parameterless ctor or ctor params matching the columns.");

Type guard

static bool IsMaterializable(Type t) => t.GetConstructor(Type.EmptyTypes) is not null || t.GetConstructors().Any(c => c.GetParameters().Length > 0);

Prevention

When it happens

Trigger: Mapping a query onto a class/struct that has only constructors whose parameter names do not match any result columns, or no public constructor at all (e.g. an interface, an abstract class, a class with only a private ctor, or a DTO whose ctor params differ from the column names). Also when column names differ from both property names and ctor parameter names.

Common situations: Mapping to a record/struct whose constructor parameter names do not match the SQL column names; mapping onto an interface; a column renamed in the DB without updating the DTO ctor; a type with no default ctor where the only ctor takes unrelated types.

Related errors


AI-assisted analysis of DapperLib/Dapper@72a54c475f (2026-08-13). Data as JSON: /api/errors/1844fbf7289731f4. Report an issue: GitHub.