dotnet/aspnetcore · error · InvalidOperationException
The method {methodInfo} cannot be used as an event handler b
Error message
The method {methodInfo} cannot be used as an event handler because it declares more than one parameter. What it means
Blazor event handlers (@onclick, @oninput, etc.) reference C# methods whose signatures the framework inspects via EventArgsTypeCache.GetEventArgsType. When a method declares more than one parameter, the framework cannot determine which parameter represents the event argument, so it throws InvalidOperationException. Event handlers must accept zero parameters (action-style) or exactly one parameter (the EventArgs-derived argument).
Source
Thrown at src/Components/Components/src/RenderTree/EventArgsTypeCache.cs:33
{
if (HotReloadManager.IsSupported)
{
HotReloadManager.Default.OnDeltaApplied += Cache.Clear;
}
}
public static Type GetEventArgsType(MethodInfo methodInfo)
{
return Cache.GetOrAdd(methodInfo, methodInfo =>
{
var parameterInfos = methodInfo.GetParameters();
if (parameterInfos.Length == 0)
{
return typeof(EventArgs);
}
else if (parameterInfos.Length > 1)
{
throw new InvalidOperationException($"The method {methodInfo} cannot be used as an event handler because it declares more than one parameter.");
}
else
{
var declaredType = parameterInfos[0].ParameterType;
if (typeof(EventArgs).IsAssignableFrom(declaredType))
{
return declaredType;
}
else
{
throw new InvalidOperationException($"The event handler parameter type {declaredType.FullName} for event must inherit from {typeof(EventArgs).FullName}.");
}
}
});
}
}
View on GitHub (pinned to 294cab2f9b)
Solutions
- If the handler needs additional context, wrap it in a lambda: @onclick="@(() => MyHandler(arg1, arg2))".
- If the handler needs the event args plus extra data, capture the extra data in a closure: @onclick="@(e => MyHandler(e, extraData))".
- Reduce the method to zero or one parameter to match the Blazor event handler contract.
- If zero parameters are needed for the action-style handler, remove the extra parameters and use closures to pass data.
Example fix
<!-- before -->
@onclick="OnItemClick"
@code {
void OnItemClick(MouseEventArgs e, int itemId) { } // two params
}
<!-- after -->
@onclick="@(e => OnItemClick(e, itemId))"
@code {
void OnItemClick(MouseEventArgs e, int itemId) { }
} Defensive patterns
Strategy: validation
Validate before calling
// Validate event handler method signature before binding
static bool IsValidEventHandler(MethodInfo method)
{
var parms = method.GetParameters();
return parms.Length <= 1;
}
// Use: if (IsValidEventHandler(typeof(MyComp).GetMethod("OnClick"))) { ... } Type guard
// In Razor, prefer lambdas for handlers needing extra context: // @onclick="@(e => HandleClick(e, itemId))"
Prevention
- Use lambda expressions for event handlers that need extra context, rather than multi-parameter methods.
- Keep event handler methods to zero or one (EventArgs-derived) parameters.
- Run a build-time Roslyn analyzer to flag methods used as handlers with >1 parameter.
- Review method signatures before referencing them in @on* attributes.
When it happens
Trigger: Using a method reference (not a lambda) as a Blazor event handler where the method has two or more parameters. For example, @onclick="MyHandler" where MyHandler is defined as void MyHandler(MouseEventArgs e, string extra). The framework resolves the event argument type at bind time via reflection and rejects multi-parameter methods.
Common situations: Trying to pass additional context to a handler via extra method parameters instead of a lambda closure; refactoring a method signature and adding parameters without updating event bindings; misunderstanding that Blazor event handlers can only receive the event args.
Related errors
- Unable to set property '{parameterName}' on object of type '
- Object of type '{targetType.FullName}' has a property matchi
- Object of type '{targetType.FullName}' does not have a prope
- The type '{targetType.FullName}' declares a parameter matchi
- The event handler parameter type {declaredType.FullName} for
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/4c5218c42ce5e6ff.
Report an issue: GitHub.