Using .NET file-based apps (via dotnet run app.cs) enables rapid prototyping and simplified project structure by eliminating project scaffolding.
This feature was announced for dotnet 10 just before .Net Conf 2025: https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-app/
It’s a neat way to try ideas quickly.
I tried to find out if this would work with FastEndpoints to demo an API that way.
Example (FastEndpoints + file-based app)
#:sdk Microsoft.NET.Sdk.Web
#:package FastEndpoints@7.*-*
using FastEndpoints;
var builder = WebApplication.CreateBuilder();
builder.Services.AddFastEndpoints();
var app = builder.Build();
app.UseFastEndpoints();
app.Run();
public record MyRequest(string FirstName, string LastName, int Age);
public record MyResponse(string FullName, bool IsOver18);
public class MyEndpoint : Endpoint<MyRequest, MyResponse>
{
public override void Configure()
{
Post("/api/user/create");
AllowAnonymous();
}
public override Task HandleAsync(MyRequest req, CancellationToken ct) =>
Send.OkAsync(new($"{req.FirstName} {req.LastName}", req.Age >= 18),
cancellation: ct);
}
Gotcha: JSON/AOT defaults can break “works with web”
When running with the web SDK in file-based apps, you can hit a runtime startup error like:
System.NotSupportedException: JsonTypeInfo metadata for type
'System.Collections.Generic.IEnumerable`1[System.String]' was not provided by TypeInfoResolver of type
'[AppJsonSerializerContext]'.
This is effectively a System.Text.Json source-generation/AOT mismatch: the app is configured to require generated metadata, but the required root types were not generated.
This 'gotcha' is not pointed out in the dev blog, but one of the first bullet points at the learn article does hint at it:
Key benefits include:
- Reduced boilerplate for simple applications.
- Self-contained source files with embedded configuration.
- Native AOT publishing enabled by default.
- Automatic packaging as .NET tools.
Why this happens (NativeAOT + JSON)
With NativeAOT / trimming, reflection is restricted, so System.Text.Json can't reliably do reflection-based (de)serialization.
In practice, you need to provide compile-time metadata via source generation (JsonSerializerContext / JsonSerializable), i.e. custom serialization setup for the types your endpoints bind/return.
Because this is a lot of "serialization bookkeeping" for a single-file prototype, I currently prefer disabling NativeAOT for this scenario.
Fix (per gist): disable AOT
To opt out of the default NativeAOT behavior (and avoid the JSON metadata requirement while prototyping), add this:
#:property PublishAot=false
This runs the app as regular JIT again, so System.Text.Json can use reflection and the error goes away.
You can find the entire gist at:
https://gist.github.com/EelcoLos/1c5f3c6be9ac765719ee880f3dcfec71
References
- https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-app/
- https://learn.microsoft.com/en-us/dotnet/core/sdk/file-based-apps
- https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/reflection-vs-source-generation
- https://learn.microsoft.com/en-us/dotnet/core/compatibility/serialization/8.0/publishtrimmed
Top comments (0)