Skip to content

feat(http-client-csharp): use Utf8JsonReader for untyped CollectionResult body parsing#9941

Draft
Copilot wants to merge 4 commits intomainfrom
copilot/use-utf8jsonreader-collectionresult
Draft

feat(http-client-csharp): use Utf8JsonReader for untyped CollectionResult body parsing#9941
Copilot wants to merge 4 commits intomainfrom
copilot/use-utf8jsonreader-collectionresult

Conversation

Copy link
Contributor

Copilot AI commented Mar 5, 2026

The untyped CollectionResult (no item model type) was deserializing the full response into the envelope model type just to extract the continuation token or next link. This PR replaces that with targeted Utf8JsonReader parsing that reads only the needed properties.

Changes

  • Utf8JsonReaderSnippets.cs — Added ValueTextEquals(string) and Skip() snippet helpers
  • JsonTokenTypeSnippets.cs — Added PropertyName enum value
  • CollectionResultDefinition.cs — New code generation path for untyped CollectionResult (when ItemModelType == null) at InputResponseLocation.Body:
    • AssignAndCheckNextPageVariable: uses Utf8JsonReader instead of model cast
    • BuildGetContinuationToken: uses Utf8JsonReader instead of model cast
    • New helpers: BuildReadNextPageWithUtf8JsonReader, BuildReaderLoopForSegments (recursive for nested paths), BuildTerminalPropertyReadStatements
    • Handles both string (continuation token) and Uri (next link) target types
  • Test data files — Updated all 10 untyped body test cases; typed *OfT variants unchanged

Generated code example

Before (full model deserialization):

nextToken = ((Page)result).NextPage;

After (targeted JSON read):

nextToken = null;
BinaryData data = result.GetRawResponse().Content;
Utf8JsonReader reader = new Utf8JsonReader(data.ToMemory().Span);
reader.Read();
while (reader.Read())
{
    if (((reader.TokenType == JsonTokenType.PropertyName) && reader.ValueTextEquals("nextPage")))
    {
        reader.Read();
        nextToken = reader.GetString();
        break;
    }
    if (((reader.TokenType == JsonTokenType.StartObject) || (reader.TokenType == JsonTokenType.StartArray)))
    {
        reader.Skip();
    }
}

Nested paths (e.g. ["nestedNext", "nextPage"]) are supported via recursively generated inner while loops.

Original prompt

This section details on the original issue you should resolve

<issue_title>Consider using Utf8JsonReader for CollectionResult</issue_title>
<issue_description>For the untyped CollectionResult that lets you iterate through ClientResult, we still deserialize into the internal envelope type to get the continuation token/next link. This is not as efficient as using Utf8JsonReader to just get the specific properties we are interested in. Things to keep in mind is that this would need to handle nested continuation tokens. </issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Mar 5, 2026
Copilot AI and others added 2 commits March 6, 2026 00:00
…odel deserialization

Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
Copilot AI changed the title [WIP] Consider using Utf8JsonReader for CollectionResult feat(http-client-csharp): use Utf8JsonReader for untyped CollectionResult body parsing Mar 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider using Utf8JsonReader for CollectionResult

2 participants