JasperFx / lamar

Fast Inversion of Control Tool and Successor to StructureMap
https://jasperfx.github.io/lamar
MIT License
563 stars 118 forks source link

IEnumerable<> controller parameters do not bind from request body by default - Asp.net Core 8 #391

Closed rizi closed 6 months ago

rizi commented 7 months ago

Hi,

When using a very simple MVC controller (not minimal api), the parameter of the method UpdateAsync (have a look at the sample below) will not be created by the model binder of asp.net but by lamar.

As far as I understand (after debugging Lamar) the issue is related to this code: The method IsService (from Microsoft.Extensions.DependencyInjection.IServiceProviderIsService) in Lamar.IoC.Scope calls Lamar.ServiceGraph.CanBeServiceByNetCoreRules() and it returns true and I think that's the problem, in this case it should return false. The question is: "is it possible for lamar to distinguish the different "use-cases" and return false in this case"?

To mitigate this problem you can add the [FromBody] Attribtute before the updateCommands parameter, like so:

public async Task UpdateAsync([FromBody] IReadOnlyCollection<UpdateCommand> updateCommands) {} 

However this can cause some additional work in our solutions (and with have quite a lot of them ;) ) and it should not be necessary, because complex types will normaly automatically be infered from the body.

There was a very similar issue by MS, but this has been fixed a while ago: https://github.com/dotnet/aspnetcore/issues/45162

Any help would highly be appreciated.

Sample to reproduce

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase {

  [HttpPut]
  public async Task UpdateAsync(IReadOnlyCollection<UpdateCommand> updateCommands)
    {
        //updateCommand is always empty
        await Task.CompletedTask;
    }
}

public record UpdateCommand(string Id);
rizi commented 7 months ago

@jeremydmiller PR #392 fixes this issue.

br