0

With minimalistic API how does MapGet automatically fill parameters from querystring?

With minimalistic API the following is possible:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("api/Students/Grades", StudentsDataContext.GetGradesAsync).RequireAuthorization("Admin");

//...

public class Grade
{
    public string? Subject { get; set; }
    public int GradePercentage { get; set; } = 0;
}

public class StudentsDataContext
{
    public static async Task<List<Grade>> GetGradesAsync(int? studentId, ClaimsPrincipal user, CancellationToken ct))
    {
        // Gets grades from database...
        return new List<Grade>() {
              new () { Subject = "Algebra", GradePercentage=95 },
              new () { Subject = "English", GradePercentage=90 }
        };
    }
}

When you call: /api/Students/Grades?studentId=5 magically, studentId is passed to the GetGradesAsync, as well as ClaimsPrinicipal, and CancellationToken. enter image description here

How does this witchcraft work? Is it possible to learn this power of the darkside?

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
Sudip Shrestha
  • 441
  • 4
  • 12
  • 1
    ... the code is opensource ... what is stopping you from study the code? ... but basically you can get method parameters via reflection ... you can check which parameters you can inject from DI continer ... the rest you may try to obtain from query string – Selvin Jan 12 '23 at 15:06
  • @Selvin I looked for it. In dotnet GitHub, I only found examples. I couldn't find the source for MapGet. – Sudip Shrestha Jan 12 '23 at 15:12
  • 1
    This is already being done in ASP core beforehand. It is called [model binding](https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding) – Oliver Jan 12 '23 at 15:14
  • 1
    https://dotnetfiddle.net/xs13OE then check if parameters are injected from DI ... if not - then get try to parse whatever(query string, path... ) ... it's pretty easy to imagine – Selvin Jan 12 '23 at 15:25
  • 1
    @SudipShrestha: it's basically reflection. The aspnet runtime checks your method and tries to find out how to collect all the parameters. The DI container binds services. Request data bind query string values. Then runtime just calls you. No witchcraft at all. – Wiktor Zychla Jan 12 '23 at 16:06
  • https://andrewlock.net/behind-the-scenes-of-minimal-apis-3-exploring-the-model-binding-logic-of-minimal-apis/ – davidfowl Jan 23 '23 at 03:51

1 Answers1

1

The link you have provided describes the rules of the parameter binding in Minimal APIs. In the nutshell it is pretty simple - the request handler delegate is analyzed (via some reflection+runtime code generation or source generation at build time I suppose) and actual handler is created were all parameters are processed accordingly and passed to user defined one.

I have not spend much time so the following can be not entirely correct, but the starting point of the investigation how does it actually work would be EndpointRouteBuilderExtensions which leads to RequestDelegateFactory (see AddRouteHandler call which fills List<RouteEntry> _routeEntries which is later processed with CreateRouteEndpointBuilder method, which calls CreateHandlerRequestDelegate) which should contain all the actual "magic".

Guru Stron
  • 102,774
  • 10
  • 95
  • 132