Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

De-duplicate parameter binding documentation across quick reference and dedicated article #36253

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
wadepickett merged 8 commits into main from copilot/de-duplicate-parameter-binding-docs
Oct 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions aspnetcore/fundamentals/minimal-apis.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@ description: Provides an overview of Minimal APIs in ASP.NET Core
ms.author: wpickett
content_well_notification: AI-contribution
monikerRange: '>= aspnetcore-6.0'
ms.date: 09/08/2025
ms.date: 10/23/2025
uid: fundamentals/minimal-apis
ai-usage: ai-assisted
---

<!-- When working on this file, open all the LATEST VERSION MD files in ~/fundamentals/minimal-apis/includes/ and search for the target text -->
<!--
Editorial note: This file is a quick reference summary:
- When working on this file, open all the LATEST VERSION MD files in ~/fundamentals/minimal-apis/includes/ and search for the target text.
- Only include brief overviews, essential lists, and basic examples in this file.
- Do NOT add detailed explanations, advanced scenarios, or troubleshooting—move those to dedicated include files (for example: parameter-binding8-10.md) and link to them from here if needed.
- All in-depth content should be placed in the appropriate in-depth include file for maintainability and clarity.
- Use H3 (###) for section headings within this include.
-->

# Minimal APIs quick reference

Expand Down Expand Up @@ -68,7 +75,7 @@ The <xref:System.Delegate> arguments passed to these methods are called "route h

## Parameter binding

[!INCLUDE [](~/fundamentals/minimal-apis/includes/parameter-binding8-10.md)]
[!INCLUDE [](~/fundamentals/minimal-apis/includes/parameter-binding-summary8-10.md)]

## Json+PipeReader deserialization in minimal APIs

Expand Down
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ The <xref:System.Delegate> arguments passed to these methods are called "route h

## Parameter binding

[!INCLUDE [](~/fundamentals/minimal-apis/includes/parameter-binding8-10.md)]
[!INCLUDE [](~/fundamentals/minimal-apis/includes/parameter-binding-summary8-10.md)]

## Responses

Expand Down
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ The <xref:System.Delegate> arguments passed to these methods are called "route h

## Parameter binding

[!INCLUDE [](~/fundamentals/minimal-apis/includes/parameter-binding8-10.md)]
[!INCLUDE [](~/fundamentals/minimal-apis/includes/parameter-binding-summary8-10.md)]

## Responses

Expand Down
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
:::moniker range=">= aspnetcore-8.0"

Parameter binding is the process of converting request data into strongly typed parameters that are expressed by route handlers. A binding source determines where parameters are bound from. Binding sources can be explicit or inferred based on HTTP method and parameter type.

Supported binding sources:

* Route values
* Query string
* Header
* Body (as JSON)
* Form values
* Services provided by dependency injection
* Custom

The following GET route handler uses some of these parameter binding sources:

:::code language="csharp" source="~/fundamentals/minimal-apis/7.0-samples/WebMinAPIs/Program.cs" id="snippet_pbg" highlight="8-11":::

### Key parameter binding features

* **Explicit binding**: Use attributes like `[FromRoute]`, `[FromQuery]`, `[FromHeader]`, `[FromBody]`, `[FromForm]`, and `[FromServices]` to explicitly specify binding sources.
* **Form binding**: Bind form values using `[FromForm]` attribute, including support for `IFormFile` and `IFormFileCollection` for file uploads.
* **Complex types**: Bind to collections and complex types from forms, query strings, and headers.
* **Custom binding**: Implement custom binding logic using `TryParse`, `BindAsync`, or the `IBindableFromHttpContext<T>` interface.
* **Optional parameters**: Support nullable types and default values for optional parameters.
* **Dependency injection**: Parameters are automatically bound from services registered in the DI container.
* **Special types**: Automatic binding for `HttpContext`, `HttpRequest`, `HttpResponse`, `CancellationToken`, `ClaimsPrincipal`, `Stream`, and `PipeReader`.

---

**Learn more:** For detailed information on parameter binding including advanced scenarios, validation, binding precedence, and troubleshooting, see <xref:fundamentals/minimal-apis/parameter-binding>.


:::moniker-end
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ The parameters in the preceding examples are all bound from request data automat

:::code language="csharp" source="~/fundamentals/minimal-apis/7.0-samples/WebMinAPIs/Snippets/Program.cs" id="snippet_ManualRequestBinding" highlight="3-5,12":::

### Explicit Parameter Binding
## Explicit Parameter Binding

Attributes can be used to explicitly declare where parameters are bound from.

Expand All @@ -49,7 +49,7 @@ Attributes can be used to explicitly declare where parameters are bound from.
| `service` | Provided by dependency injection |
| `contentType` | header with the name `"Content-Type"` |

#### Explicit binding from form values
### Explicit binding from form values

The [`[FromForm]`](xref:Microsoft.AspNetCore.Mvc.FromFormAttribute) attribute binds form values:

Expand All @@ -65,7 +65,7 @@ For more information, see the section on [AsParameters](#parameter-binding-for-a

The [complete sample code](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/fundamentals/minimal-apis/samples/IFormFile) is in the [AspNetCore.Docs.Samples](https://github.com/dotnet/AspNetCore.Docs.Samples) repository.

#### Secure binding from IFormFile and IFormFileCollection
### Secure binding from IFormFile and IFormFileCollection

Complex form binding is supported using <xref:Microsoft.AspNetCore.Http.IFormFile> and <xref:Microsoft.AspNetCore.Http.IFormFileCollection> using the [`[FromForm]`](xref:Microsoft.AspNetCore.Mvc.FromFormAttribute):

Expand All @@ -77,13 +77,13 @@ For more information, see [Form binding in minimal APIs](https://andrewlock.net/

The [complete sample code](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/fundamentals/minimal-apis/samples/FormBinding) is in the [AspNetCore.Docs.Samples](https://github.com/dotnet/AspNetCore.Docs.Samples) repository.

### Parameter binding with dependency injection
## Parameter binding with dependency injection

Parameter binding for minimal APIs binds parameters through [dependency injection](xref:fundamentals/dependency-injection) when the type is configured as a service. It's not necessary to explicitly apply the [`[FromServices]`](xref:Microsoft.AspNetCore.Mvc.FromServicesAttribute) attribute to a parameter. In the following code, both actions return the time:

:::code language="csharp" source="~/release-notes/aspnetcore-7/samples/ApiController/Program.cs" id="snippet_min" highlight="8-9":::

### Optional parameters
## Optional parameters

Parameters declared in route handlers are treated as required:

Expand Down Expand Up @@ -127,7 +127,7 @@ The preceding code calls the method with a null product if no request body is se

See the [Binding Failures](#bf) section for more information.

### Special types
## Special types

The following types are bound without explicit attributes:

Expand Down Expand Up @@ -159,7 +159,7 @@ The following types are bound without explicit attributes:

<a name="rbs"></a>

#### Bind the request body as a `Stream` or `PipeReader`
### Bind the request body as a `Stream` or `PipeReader`

The request body can bind as a [`Stream`](/dotnet/api/system.io.stream) or [`PipeReader`](/dotnet/api/system.io.pipelines.pipereader) to efficiently support scenarios where the user has to process data and:

Expand All @@ -184,7 +184,7 @@ The following code shows the complete `Program.cs` file:
* The request body isn't buffered by default. After the body is read, it's not rewindable. The stream can't be read multiple times.
* The `Stream` and `PipeReader` aren't usable outside of the minimal action handler as the underlying buffers will be disposed or reused.

#### File uploads using IFormFile and IFormFileCollection
### File uploads using IFormFile and IFormFileCollection

The following code uses <xref:Microsoft.AspNetCore.Http.IFormFile> and <xref:Microsoft.AspNetCore.Http.IFormFileCollection> to upload file:

Expand All @@ -194,7 +194,7 @@ Authenticated file upload requests are supported using an [Authorization header]

<a name="bind8"></a>

#### Binding to forms with IFormCollection, IFormFile, and IFormFileCollection
### Binding to forms with IFormCollection, IFormFile, and IFormFileCollection

Binding from form-based parameters using <xref:Microsoft.AspNetCore.Http.IFormCollection>, <xref:Microsoft.AspNetCore.Http.IFormFile>, and <xref:Microsoft.AspNetCore.Http.IFormFileCollection> is supported. [OpenAPI](xref:fundamentals/openapi/aspnetcore-openapi) metadata is inferred for form parameters to support integration with [Swagger UI](xref:tutorials/web-api-help-pages-using-swagger).

Expand All @@ -212,7 +212,7 @@ For more information, see [Form binding in minimal APIs](https://andrewlock.net/

<a name="bindcc"></a>

### Bind to collections and complex types from forms
## Bind to collections and complex types from forms

Binding is supported for:

Expand Down Expand Up @@ -244,7 +244,7 @@ isCompleted: false

<a name="bindar"></a>

### Bind arrays and string values from headers and query strings
## Bind arrays and string values from headers and query strings

The following code demonstrates binding query strings to an array of primitive types, string arrays, and [StringValues](/dotnet/api/microsoft.extensions.primitives.stringvalues):

Expand Down Expand Up @@ -279,7 +279,7 @@ The following code binds to the header key `X-Todo-Id` and returns the `Todo` it

<a name="asparam7"></a>

### Parameter binding for argument lists with [AsParameters]
## Parameter binding for argument lists with [AsParameters]

<xref:Microsoft.AspNetCore.Http.AsParametersAttribute> enables simple parameter binding to types and not complex or recursive model binding.

Expand Down Expand Up @@ -319,15 +319,15 @@ Using a `struct` with `AsParameters` can be more performant than using a `record

The [complete sample code](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/fundamentals/minimal-apis/samples/arg-lists) in the [AspNetCore.Docs.Samples](https://github.com/dotnet/AspNetCore.Docs.Samples) repository.

### Custom Binding
## Custom Binding

There are three ways to customize parameter binding:

1. For route, query, and header binding sources, bind custom types by adding a static `TryParse` method for the type.
1. Control the binding process by implementing a `BindAsync` method on a type.
1. For advanced scenarios, implement the <xref:Microsoft.AspNetCore.Http.IBindableFromHttpContext%601> interface to provide custom binding logic directly from the `HttpContext`.

#### TryParse
### TryParse

`TryParse` has two APIs:

Expand All @@ -340,7 +340,7 @@ The following code displays `Point: 12.3, 10.1` with the URI `/map?Point=12.3,10

:::code language="csharp" source="~/fundamentals/minimal-apis/7.0-samples/WebMinAPIs/Program.cs" id="snippet_cb":::

#### BindAsync
### BindAsync

`BindAsync` has the following APIs:

Expand All @@ -355,7 +355,7 @@ The following code displays `SortBy:xyz, SortDirection:Desc, CurrentPage:99` wit

<a name="bf"></a>

#### Custom parameter binding with `IBindableFromHttpContext`
### Custom parameter binding with `IBindableFromHttpContext`

ASP.NET Core provides support for custom parameter binding in Minimal APIs using the <xref:Microsoft.AspNetCore.Http.IBindableFromHttpContext%601> interface. This interface, introduced with C# 11's static abstract members, allows you to create types that can be bound from an HTTP context directly in route handler parameters.

Expand All @@ -381,7 +381,7 @@ You can also implement validation within your custom binding logic:

[View or download the sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/minimal-apis/10.0-samples/CustomBindingExample) ([how to download](xref:index#how-to-download-a-sample))

### Binding failures
## Binding failures

When binding fails, the framework logs a debug message and returns various status codes to the client depending on the failure mode.

Expand All @@ -393,7 +393,7 @@ When binding fails, the framework logs a debug message and returns various statu
| Failure to deserialize JSON body |doesn't matter|body|400|
| Wrong content type (not `application/json`) |doesn't matter|body|415|

### Binding Precedence
## Binding Precedence

The rules for determining a binding source from a parameter:

Expand Down Expand Up @@ -423,27 +423,27 @@ The rules for determining a binding source from a parameter:
1. If the parameter type is a service provided by dependency injection, it uses that service as the source.
1. The parameter is from the body.

### Configure JSON deserialization options for body binding
## Configure JSON deserialization options for body binding

The body binding source uses <xref:System.Text.Json?displayProperty=fullName> for deserialization. It is ***not*** possible to change this default, but JSON serialization and deserialization options can be configured.

#### Configure JSON deserialization options globally
### Configure JSON deserialization options globally

Options that apply globally for an app can be configured by invoking <xref:Microsoft.Extensions.DependencyInjection.HttpJsonServiceExtensions.ConfigureHttpJsonOptions%2A>. The following example includes public fields and formats JSON output.

:::code language="csharp" source="~/fundamentals/minimal-apis/7.0-samples/WebMinJson/Program.cs" id="snippet_confighttpjsonoptions" highlight="3-6":::

Since the sample code configures both serialization and deserialization, it can read `NameField` and include `NameField` in the output JSON.

#### Configure JSON deserialization options for an endpoint
### Configure JSON deserialization options for an endpoint

<xref:Microsoft.AspNetCore.Http.HttpRequestJsonExtensions.ReadFromJsonAsync%2A> has overloads that accept a <xref:System.Text.Json.JsonSerializerOptions> object. The following example includes public fields and formats JSON output.

:::code language="csharp" source="~/fundamentals/minimal-apis/7.0-samples/WebMinJson/Program.cs" id="snippet_readfromjsonasyncwithoptions" highlight="5-8,12":::

Since the preceding code applies the customized options only to deserialization, the output JSON excludes `NameField`.

### Read the request body
## Read the request body

Read the request body directly using a <xref:Microsoft.AspNetCore.Http.HttpContext> or <xref:Microsoft.AspNetCore.Http.HttpRequest> parameter:

Expand Down

AltStyle によって変換されたページ (->オリジナル) /