I am attempting to make use of the aspnet minimal api. I am looping through classes with a specific interface and then for each method I am generating a handler for the app.MapPost. When I do this and run the app. If I call the API or Swagger, I get System.InvalidOperationException: Encountered a parameter of type 'System.Runtime.CompilerServices.Closure' without a name. Parameters must have a name.
I have simplified it down to ensure that it was not the typecasting I was doing. Each version does the same, but obviously, there is something different. The desire is to be able to use CreateHandler in a more generic manner.
Target Framework = 7.0.
Code:
_ = app.MapPost("api/services/security/users/list", CreateHandler()); // Error
_ = app.MapPost("api/services/security/users/list", CreateHandler_Exp()); // Error
_ = app.MapPost("api/services/security/users/list", CreateHandler_Func()); // Works
// Error
private static Func<ListUsersArgs, IUserService, List<UserListItem>> CreateHandler_Func() {
return (ListUsersArgs model, IUserService svc) => svc.List(model);
}
// Error
private static Func<ListUsersArgs, IUserService, List<UserListItem>> CreateHandler_Exp() {
Expression<Func<ListUsersArgs, IUserService, List<UserListItem>>> e = (model, us) => us.List(model);
var l = e.Compile();
return l;
}
// Works
private static Func<ListUsersArgs, IUserService, List<UserListItem>> CreateHandler() {
var serviceType = typeof(IUserService);
var method = serviceType.GetMethods().First(m => m.Name == "List");
var modelObjParam = Expression.Parameter(typeof(ListUsersArgs), "model");
var svcObjParam = Expression.Parameter(serviceType, "svc");
var executeExpression = Expression.Call(svcObjParam, method.Name, null, modelObjParam);
//var blockExpression = Expression.Block(executeExpression);
var lambda = Expression.Lambda<Func<ListUsersArgs, IUserService, List<UserListItem>>>(executeExpression, modelObjParam, svcObjParam);
return lambda.Compile();
}