Skip to content
Draft
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
4 changes: 4 additions & 0 deletions aspnetcore/fundamentals/minimal-apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ The <xref:System.Delegate> arguments passed to these methods are called "route h

[!INCLUDE [](~/fundamentals/minimal-apis/includes/parameter-binding10.md)]

## Json+PipeReader deserialization in minimal APIs

[!INCLUDE [](~/includes/net10pipereader.md)]

## Validation support in Minimal APIs

Support for validation in Minimal APIs is now available. This feature allows you to request validation of data sent to your API endpoints. Enabling validation allows the ASP.NET Core runtime to perform any validations defined on the:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,4 +427,8 @@ The preceding code:
* Accesses the request body using <xref:Microsoft.AspNetCore.Http.HttpRequest.BodyReader?displayProperty=nameWithType>.
* Copies the request body to a local file.

## JsonPipeReader deserialization in minimal APIs

[!INCLUDE [](~/includes/net10pipereader.md)]

:::moniker-end
54 changes: 54 additions & 0 deletions aspnetcore/includes/net10pipereader.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!--
This include file is used in
minimal-apis.md
parameter-binding10.md
model-binding.md
-->

Srtarting in .NET 10, the following functional areas of ASP.NET Core use overloads of `JsnSerializer.DeserializeAsync` based on PipeReader instead of Stream:

* Minimal APIs (parameter binding, read request body)
* MVC (input formatters, model )
* The <xref:Microsoft.AspNetCore.Http.HttpRequestJsonExtensions?displayProperty=nameWithType> methods

For most applications, a transition from Stream to PipeReader provides better performance without requiring changes in application code. But if your application has a custom converter, the converter might not handle <xref:System.Text.Json.Utf8JsonReader.HasValueSequence%2A?displayProperty=nameWithType> correctly. If it doesn't, the result could be errors such as <xref:System.ArgumentOutOfRangeException>with no warning, or missing data when deserializing. You have the following options for getting your converter to work without PipeReader-related errors

## Option 1: Temporary workaround

The quick workaround is to go back to using Stream without PipeReader support. To implement this option, set the "Microsoft.AspNetCore.UseStreamBasedJsonParsing" AppContext switch to "true". We recommend that you do this only as a temporary workaround, and update your converter to support`HasValueSequence` as soon as possible. The switch might be removed in .NET 11. Its purpose was to give developers time to get their converters updated.

## Option 2: A quick fix for `JsonConverter` implementations

For this fix, you allocate an array from the `ReadOnlySequence`. This example is what the code would look like::

```csharp
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
// previous code
}
```

## Option 3: ## Option 3: A more complicated but better performing fix

This fix involves setting up a separate code path for the `ReadOnlySequence` handling:

```csharp
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.HasValueSequence)
{
reader.ValueSequence;
// ReadOnlySequence optimized path
}
else
{
reader.ValueSpan;
// ReadOnlySpan optimized path
}
}
```

For more information, see
* <xref:System.Text.Json.Serialization.JsonConverter?displayProperty=nameWithType>
* [github.com/dotnet/aspnetcore/pull/6289](https://github.com/dotnet/aspnetcore/pull/62895)
12 changes: 10 additions & 2 deletions aspnetcore/mvc/models/model-binding.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ ms.date: 07/19/2025
ai-usage: ai-assisted
uid: mvc/models/model-binding
---

<!-- Note the use of inline moniker tags at the end of the file. -->
# Model Binding in ASP.NET Core

[!INCLUDE[](~/includes/not-latest-version.md)]
Expand Down Expand Up @@ -723,6 +723,15 @@ If an instance of the type isn't registered in the dependency injection containe
For nullable parameters, ensure that the parameter isn't `null` before accessing it.

## Additional resources
:::moniker-end
:::moniker range=">= aspnetcore-10.0"

## Json+PipeReader deserialization in MVC

[!INCLUDE [](~/includes/net10pipereader.md)]

:::moniker-end
:::moniker range=">= aspnetcore-8.0"

* [View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/mvc/models/model-binding/samples) ([how to download](xref:fundamentals/index#how-to-download-a-sample))
* <xref:mvc/models/validation>
Expand All @@ -731,4 +740,3 @@ For nullable parameters, ensure that the parameter isn't `null` before accessing
:::moniker-end

[!INCLUDE[](~/mvc/models/model-binding/includes/model-binding7.md)]

Loading