ASP.NET Core Route Tooling Enhancements in .NET 8

James Newton-King

ASP.NET Core is built on routing. Minimal APIs, Web APIs, Razor Pages, and Blazor all use routes to customize how HTTP requests map to your code.

In .NET 8 we’re investing in a suite of new features to make routing easier to learn and use. These include:

  • Route syntax highlighting
  • Autocomplete of parameter and route names
  • Autocomplete of route constraints
  • Route analyzers and fixers
  • Support for Minimal APIs, Web APIs, and Blazor

Grouped all together, we call these new features route tooling. Deep tooling integration around routes is new ground for the ASP.NET Core team, and we’re excited about the productivity improvements route tooling brings to ASP.NET Core developers.

Route syntax highlighting

ASP.NET Core has a stable, well-defined syntax for routing. It supports a variety of features:

  • Parameters – /product/{id}
  • Parameter constraints – /product/{id:int}
  • Parameter defaults – /{page=Home}
  • Optional parameters – /files/{filename}.{ext?}
  • Catch-all parameters – /blog/{*slug}
  • Token replacement – /api/[controller]/[action]

Different parts of routes are now highlighted in the IDE, making routes easier to understand. Syntax highlighting and an analyzer that alerts you to route syntax errors on build should make routes much easier for developers to use.

Route syntax highlighting

Autocomplete of parameter and route names

A popular ASP.NET Core feature is route value binding. When a method and route parameter’s name match on Minimal and Web APIs, the value is automatically passed to the method.

Route tooling adds autocompletion to speed up writing your APIs and reduce typos between route and method parameter names.

Autocomplete of parameter and route names

Autocomplete of route constraints

ASP.NET Core includes 18 built-in route constraints. Route constraints limit what values a route accepts. For example, /products/{id:int} limits id to only accept integers.

A small sample of route constraints:

  • int – Matches any integer
  • bool – Matches true or false
  • datetime – Matches a valid DateTime value
  • minlength(value) – String must be at least the specified number of characters
  • maxlength(value) – String must be no more than the specified number of characters
  • alpha – String must consist of one or more alphabetical characters
  • regex(expression) – String must match the regular expression

There’s great documentation for constraints, but looking up docs is still a pain. Route tooling fixes that by adding constraint autocompletion. A list of constraints is now available in the IDE.

Route analyzers and fixers

We’ve thought hard about common problems developers run into when using routes, and we’ve added many new analyzers and fixes to address those issues and make routing easier to use.

New analyzers and fixers include:

Route syntax analyzer

As you write and compile your app, route syntax errors are reported in real-time. Some common syntax mistakes include:

  • Forgetting to close a parameter with }: /products/{id:alpha
  • Multiple route parameters with the same name: /api/{version}/product/{version}
  • Segments after a catch-all parameter: /blog/{*slug}/{date}

Receiving feedback as you write a route is a powerful feature. Before, running your app was the only way to test whether a route worked. Trial and error isn’t a great or productive experience. Trial and error is especially frustrating to developers learning routing for the first time.

We’re excited about the productivity boost real-time routing feedback will provide to developers!

Route syntax analyzer

Mismatched parameter optionality analyzer and fixer

Routing supports optional parameters. For example, /blog/archive/{date?} matches /blog/archive and /blog/archive/2023-4-1.

If an optional parameter is bound to a non-nullable method parameter, such as DateTime in the example above, there isn’t anything to bind to the parameter. DateTime must have a value, so ASP.NET Core throws an error.

The mismatched parameter optionality analyzer detects and warns of this situation. A fixer automatically modifies the method parameter to be nullable:

app.MapGet("/blog/archive/{date?}", (DateTime? date) =>
    return (date == null) ? GetAllBlogPosts() : GetBlogPostsByDate(date.Value);

Ambiguous Minimal API and Web API route analyzer

Suppose multiple routes match the same URL. ASP.NET Core doesn’t know which route to use and throws an error. Writing ambiguous routes is an easy mistake, especially if you’re new to routing.

app.MapGet("/product/{name}", (string name) => ...);
app.MapGet("/product/{id}", (int id) => ...);

The preceding Minimal API looks like it works because the route parameter names and API types are different. Actually, these routes are functionally the same and will create an ambiguous match.

The ambiguous route analyzer detects common ambiguous matches and provides a warning. The fix in this situation is to add route constraints:

app.MapGet("/product/{name:alpha}", (string name) => ...);
app.MapGet("/product/{id:int}", (int id) => ...);

Supports Minimal APIs, Web APIs, and Blazor

Minimal APIs, Web APIs, Razor Pages, Blazor, and more use routes. Route tooling supports all the places you use routes in ASP.NET Core.

Supported frameworks

Route tooling is built on Roslyn, and features automatically light up depending on your IDE.

Try it now

Route tooling is out now in .NET 8 previews. Try it today:

  1. Download the latest .NET 8 preview.
  2. Launch Visual Studio 2022 and create a new website with the ASP.NET Core Empty template for .NET 8.0.
  3. Open Program.cs and start adding new minimal APIs. For example, app.MapGet("/product/{id:int}", (int id) => ...).

Let us know what you think about these new features by filing issues on GitHub.

Thanks for trying out ASP.NET Core and route tooling!


Discussion is closed. Login to edit/delete existing comments.

  • Kenneth Hoff 3

    You are very vague about support here – unless I missed it. You say “The IDE” as if there’s only one, but there are many. Visual Studio is only mentioned in the “Try it now” section, but I have a suspicion it’s implied everywhere else

    Is this a part of the Roslyn Analyzer – meaning it’s supported by MSBuild directly – or is this a Visual Studio-exclusive?

    • James Newton-KingMicrosoft employee 5

      I think you missed this part: “Route tooling is built on Roslyn, and features automatically light up depending on your IDE.”.

      I can go into some more detail. Most of route tooling is built from common Roslyn extensions: analyzers, fixers, and completion providers. For example, analyzers should work everywhere, including reporting warnings when an app is built via the command line with dotnet build or MSBuild.

      Syntax highlighting is a more advanced feature. Like everything else, it’s built on Roslyn. Route tooling gets text spans from Roslyn, parses the text and identifies different parts as a route template, and uses Roslyn to classify the text span parts. However, some IDEs might not use that data.

    • Acchita Bajpai 1

      Regarding the Roslyn Analyzer, it is a language feature of the .NET Compiler Platform (also known as “Roslyn”) and is not limited to Visual Studio. Therefore, it can be used with other tools that support the .NET Compiler Platform, such as MSBuild or the .NET Command-Line Interface (CLI).

      However, the specific integration of the Roslyn Analyzer with an IDE may vary depending on the IDE. For example, Visual Studio provides built-in integration for the Roslyn Analyzer, allowing it to be used seamlessly within the IDE. Other IDEs may require additional configuration or plugins to enable the same functionality.

      In summary, while the Roslyn Analyzer is not limited to Visual Studio and can be used with other tools that support the .NET Compiler Platform, the level of integration with a specific IDE may vary.

    • Tanveer Badar 0

      If you are asking about support in OmniSharp, then the analyzer portion will work since it supports running roslyn analyzers. If it is about VS Code or Rider, then you are asking the wrong person.

Feedback usabilla icon