You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix property lookup to support inheritance in pagination response models (microsoft#9419)
The emitter failed when pagination properties (`@nextLink`,
`@pageItems`) were defined in base models rather than directly on the
response model. Property lookups used `Properties.First()` which only
searched direct properties, causing `InvalidOperationException` for
inherited properties.
## Changes
- **Added recursive property lookup**: New
`FindPropertyInModelHierarchy()` method traverses the model inheritance
chain to locate properties defined in base classes
- **Updated `CollectionResultDefinition.GetNextPagePropertyType()`**:
Replaced direct property access with hierarchy-aware lookup
- **Updated `ModelProviderSnippets.BuildPropertyAccessExpression()`**:
Applied same pattern for consistency across property access paths
- **Added test coverage**: 4 test cases covering sync/async and
generic/non-generic scenarios with inherited pagination properties
## Example
Now supports this pattern:
```typespec
model ResponseList {
@nextlink
nextLink?: string;
}
model FooResponseList extends ResponseList {
@pageItems
value?: FooResource[];
}
```
Previously, the emitter would throw when trying to locate `nextLink` on
`FooResponseList` since it only checked direct properties.
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>[http-client-csharp] failed to find nested nextLink
property for a list operation</issue_title>
> <issue_description>If the response model is inherited from another
model that only defines `nextLink`, like this:
> ``` js
> model ResponseList {
> /**
> * The uri to fetch the next page of resources. Call ListNext() fetches
next page of resources.
> */
> @nextlink
> nextLink?: string;
> }
>
> model FooResponseList extends ResponseList {
> /**
> * List of resources.
> */
> @pageItems
> value?: FooResource[];
> }
> ```
> Then the emitter throws an exception because it doesn’t check for
nested `nextLink` values. This results in an error like the following:
> ```
> Sequence contains no matching element
> at System.Linq.ThrowHelper.ThrowNoMatchException()
> at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2
predicate)
> at
Microsoft.TypeSpec.Generator.ClientModel.Providers.CollectionResultDefinition.GetNextPagePropertyType()
> at
Microsoft.TypeSpec.Generator.ClientModel.Providers.CollectionResultDefinition..ctor(ClientProvider
client, InputPagingServiceMethod serviceMethod, CSharpType
itemModelType, Boolean isAsync)
> at
Azure.Generator.Providers.AzureCollectionResultDefinition..ctor(ClientProvider
client, InputPagingServiceMethod serviceMethod, CSharpType
itemModelType, Boolean isAsync)
> at
Azure.Generator.Providers.AzureClientResponseProvider.CreateClientCollectionResultDefinition(ClientProvider
client, InputPagingServiceMethod serviceMethod, CSharpType type, Boolean
isAsync)
> at
Microsoft.TypeSpec.Generator.ClientModel.Providers.ScmMethodProviderCollection.BuildProtocolMethod(MethodProvider
createRequestMethod, Boolean isAsync, Boolean
shouldMakeParametersRequired)
> at
Microsoft.TypeSpec.Generator.ClientModel.Providers.ScmMethodProviderCollection.BuildMethods()
> at
Microsoft.TypeSpec.Generator.ClientModel.Providers.ScmMethodProviderCollection.get_MethodProviders()
> at
Microsoft.TypeSpec.Generator.ClientModel.Providers.ScmMethodProviderCollection.GetEnumerator()
> at System.Collections.Generic.List`1.AddRange(IEnumerable`1
collection)
> at
Microsoft.TypeSpec.Generator.ClientModel.Providers.ClientProvider.BuildMethods()
> at Microsoft.TypeSpec.Generator.Providers.TypeProvider.get_Methods()
> at
Microsoft.TypeSpec.Generator.ClientModel.Providers.ClientProvider.GetMethodCollectionByOperation(InputOperation
operation)
> ```</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixesmicrosoft#9418
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ArthurMa1978 <20514459+ArthurMa1978@users.noreply.github.com>
Copy file name to clipboardExpand all lines: packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/CollectionResultDefinition.cs
Copy file name to clipboardExpand all lines: packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/CollectionResultDefinitions/NextLinkTests.cs
+80Lines changed: 80 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -238,6 +238,62 @@ public void UsesValidFieldIdentifierNames()
0 commit comments