Skip to content

[Bug]: Serializer.SerializeResponseAsync writes synchronously to the target stream #399

Closed

Description

@antoineatstariongroup

What type of issue is this?

  • Bug report
  • Feature request

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of the SysML2.NET
  • I have searched open and closed issues to ensure it has not already been reported

Description

Both Serializer.SerializeResponseAsync overloads (IResponse and IEnumerable<IResponse>) perform a synchronous write on the target stream before their await writer.FlushAsync(...): the private WriteSingle and WriteMany helpers end with writer.Flush(), which calls Stream.Write.

On a stream that disallows synchronous I/O — ASP.NET Core's response body under Kestrel or TestServer, where AllowSynchronousIO is false by default — this throws:

System.InvalidOperationException: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true.
   at System.IO.Stream.Write(ReadOnlySpan`1 buffer)
   at System.Text.Json.Utf8JsonWriter.Flush()
   at SysML2.NET.Serializer.Json.Serializer.WriteMany(...)
   at SysML2.NET.Serializer.Json.Serializer.SerializeResponseAsync(IEnumerable`1 dataItems, ...)

Since the response status has usually been sent by then, an HTTP server answers 200 with an empty body. The SerializeAsync overloads (Core elements) are not affected: they use FlushAsync throughout.

Expected: the …Async methods perform no synchronous I/O on the target stream.

Suggested fix: remove writer.Flush() from WriteSingle / WriteMany and keep the trailing await writer.FlushAsync(cancellationToken) in the async callers; the synchronous SerializeResponse overloads then flush after calling the helpers.

Steps to Reproduce

  1. Host a minimal ASP.NET Core endpoint that writes a PSM response straight to HttpResponse.Body:
    await serializer.SerializeResponseAsync(new[] { new Project { Id = Guid.NewGuid() } }, SerializationModeKind.JSON, false, context.Response.Body, new JsonWriterOptions(), context.RequestAborted);
  2. Call it through Kestrel or WebApplicationFactory / TestServer.
  3. The call throws InvalidOperationException; the client receives an empty body.

A unit test can reproduce it without a host by passing a Stream whose synchronous Write throws (e.g. a Mock<Stream> that only implements WriteAsync).

System Configuration

  • SysML2.NET version: 0.25.1 (SysML2.NET.Serializer.Json)
  • Environment (Operating system, version and so on): Windows 11, ASP.NET Core 10 (Kestrel / TestServer)
  • .NET Framework version: .NET 10
  • Additional information: Mycelium Fabric works around it by serializing into a MemoryStream and copying it to the response with CopyToAsync.

Activity

  1. added a commit that references this issue on Oct 29, 2026
    07cbe5d
  2. linked a pull request that will close this issueFix #399 #401on Oct 29, 2026
  3. added a commit that references this issue on Oct 29, 2026
    1f7da99
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions