SkillAgentSearch skills...

WebApiWith.NET

Samples and resources of how to design WebApi with .NET

Install / Use

/learn @oskardudycz/WebApiWith.NET
About this skill

Quality Score

0/100

Category

Design

Supported Platforms

Universal

README

Twitter Follow Github Sponsors blog blog

WebApi with .NET

Samples and resources of how to design WebApi with .NET

Support

Feel free to create an issue if you have any questions or request for more explanation or samples. I also take Pull Requests!

💖 If this repository helped you - I'd be more than happy if you join the group of my official supporters at:

👉 Github Sponsors

Prerequisites

  1. Install .NET Core SDK 3.1 from link.
  2. Install one of IDEs:
    • Visual Studio - link - for Windows only. Community edition is available for free,
    • Visual Studio for Mac - link - for MacOS only. Available for free,
    • Visual Studio Code- link with C# plugin - Cross-platform support. Available for free,
    • Rider - link - cross-platform support. Paid, but there are available free options (for OpenSource, students, user groups etc.)

Project Configuration

Routing

From the documentation: "Routing is responsible for matching incoming HTTP requests and dispatching those requests to the app's executable endpoints."

Saying differently routing is responsible for finding exact endpoint based on the request parameters - usually based on the URL pattern matching.

Endpoint executes the logic that creates an HTTP response based on request.

To use routing and endpoints it's needed to call UseRouting and UseEndpoints extension method on app builder in Startup.Configure method. That will register routing in middleware pipeline.

Note that those methods should be registered in the order as presented above. If the order is changed then it won't be registered properly.

Route templates

Templates add flexibility to supported URL definition.

The simplest option is static URL where you have just URL, eg:

  • /Reservations/List
  • /GetUsers
  • /Orders/ByStatuses/Closed

Route parameters

Static URLs are fine for the list endpoints, but if we'd like to get a list of records.
To allow dynamic matching (eg. reservation by Id) we need to use parameters. They can be added using {parameterName} syntax. eg.

  • /Reservations/{id}
  • /users/{id}/orders/{orderId}

They don't need to be only used instead of concrete URL part. You can also do eg.:

  • /Reservations?status={reservationStatus}&user={userId} - this will get parameters from the query string and match eg. /Reservations?status=Open&userId=123 and will have status parameter equal to Open and userId equal to 123,
  • /Download/{fileName}.{extension} - this will match eg. /Download/testFile.txt and end up with two route data parameters - fileName with testFile value and extension with txt accordingly,
  • /Configuration/{entityType}Dictionary - this will match /Configuration/OrderStatusDictionary and will have entityType parameter with OrderStatus value.

You can also add catch-all parameters - {**parameterName}, that can be used as fallback when no route was found:

  • /Reservations/{id}/{**reservationPath} - this will match eg. /Reservations/123/changeStatus/confirmed and will have reservationPath parameter with changeStatus/confirmed value

It's also possible to make the parameter optional by adding ? after its name:

  • /Reservations/{id?} - this will match both /Reservations and /Reservation/123 routes

Route constraints

Route template parameters can contain constraints to narrow down the matched results. To use it you need to add constraint name after parameter name {prameter:constraintName}. There is a number of predefined route constraints, eg:

  • /Reservations/{id:guid} - will match eg. /Reservations/632863d2-5cbf-4c9f-92e1-749d264d965e but wont' match eg. /Reservations/123,
  • /Reservations/top/{limit:int:minlength(1):maxLength(10) - this will allow to pass integers between 1 and 10 for limit parameter. So it will allow to get at most top 10 reservations,
  • /Inbox?from={fromEmailAddress:regex(\\[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4})} - regex can be also used to eg. check email address or provide more advanced format check. This will match /Inbox?from=john.doe@company.com and will have fromEmailAddress parameter with john.doe@company.com value,
  • see more constraints examples in route constraint documentation.

Note - failing constraint will result with 400 - BadRequest status code, however, the messages are generic and not user friendly. So if you'd like to make them more related to your business case - it's suggested to do move it to validation inside the code.

You can also define your custom constraint. The sample use case would be when you want to provide the validation for your business id format.

See sample that validates if reservation id is built from 3 non-empty parts split by |;

public class ReservationIdConstraint : IRouteConstraint
{
    public bool Match(
        HttpContext httpContext,
        IRouter route,
        string routeKey,
        RouteValueDictionary values,
        RouteDirection routeDirection)
    {
        if (routeKey == null)
        {
            throw new ArgumentNullException(nameof(routeKey));
        }

        if (values == null)
        {
            throw new ArgumentNullException(nameof(values));
        }

        if (!values.TryGetValue(routeKey, out var value) && value != null)
        {
       

Related Skills

View on GitHub
GitHub Stars245
CategoryDesign
Updated1mo ago
Forks30

Languages

C#

Security Score

95/100

Audited on Feb 8, 2026

No findings