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

Q: OpenAPI for streamed JSON request body & asking about IAsyncEnumerable<T> input support #62391

Answered by mikekistler
ryanelian asked this question in Q&A
Discussion options

Hi ASP.NET Core team,

Scenario:

I need to accept very large JSON arrays. To avoid buffering the whole payload I read HttpRequest.Body directly and stream‐deserialize with JsonSerializer.DeserializeAsyncEnumerable<Data>().

That (hopefully) keeps memory usage low, but because the action has no [FromBody] parameter, the OpenAPI shows an empty request body.

 [HttpPost]
 [EndpointSummary("...")]
 [EndpointDescription("...")]
 [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(int))]
 [ProducesResponseType(StatusCodes.Status401Unauthorized, Type = typeof(string))]
 [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(string))]
 public async Task<ActionResult<int>> Post(CancellationToken cancellationToken)
 {
 var processedCount = 0;
 var jsonOptions = new JsonSerializerOptions
 {
 PropertyNameCaseInsensitive = true,
 };
 try
 {
 // The array can be a VERY LARGE array.
 await foreach (var data in JsonSerializer.DeserializeAsyncEnumerable<Data>(Request.Body, jsonOptions, cancellationToken))
 {
 if (data == null)
 {
 continue;
 }
 // send data to SQS / background worker here
 processedCount++;
 }
 return processedCount;
 }
 catch
 {
 return BadRequest("Invalid request body");
 }
 }

Questions

  1. How do I decorate the action so that OpenAPI documentation shows "array of Data in the request body" even though I’m reading Request.Body myself? (Is there an side-effect free attribute that you recommend? As far as my understanding if I use [FromBody] it will buffer and deserialize the content of the JSON into memory)

  2. Is manual streaming still the right approach, or can MVC now bind directly to IAsyncEnumerable?

public async Task<ActionResult<int>> Post([FromBody] IAsyncEnumerable<Data> items, CancellationToken ct)

If this is (or will soon be) supported?

  1. Any gotchas when using the manual Request.Body approach?

Related issues:

Any guidance or pointers to docs would be greatly appreciated.

Thanks for your time and for all the great work on ASP.NET Core!

You must be logged in to vote

How do I decorate the action so that OpenAPI documentation shows "array of Data in the request body"

If you are using .NET 9 and the built-in OpenAPI document generation, you could use an operation transformer to add the request body on that operation. The operation transformer will run for all operations and you'll have to filter to just the one you want to update.

Is manual streaming still the right approach, or can MVC now bind directly to IAsyncEnumerable?

I think manual streaming is still the right (only?) approach.

Any gotchas when using the manual Request.Body approach?

Just the one you've already encountered -- you need to fix the OpenAPI metadata to get an accurate API desc...

Replies: 1 comment

Comment options

How do I decorate the action so that OpenAPI documentation shows "array of Data in the request body"

If you are using .NET 9 and the built-in OpenAPI document generation, you could use an operation transformer to add the request body on that operation. The operation transformer will run for all operations and you'll have to filter to just the one you want to update.

Is manual streaming still the right approach, or can MVC now bind directly to IAsyncEnumerable?

I think manual streaming is still the right (only?) approach.

Any gotchas when using the manual Request.Body approach?

Just the one you've already encountered -- you need to fix the OpenAPI metadata to get an accurate API description.

You must be logged in to vote
0 replies
Answer selected by ryanelian
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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