#1799 - CAML queries with Joins/ProjectedFields do not return projected fields - add CSOM-based GetItems support. Closes #1799 - #1802
Conversation
|
Thanks @jeppesc11 for opening the PR. We will try to look into it ASAP |
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #1802 +/- ##
==========================================
- Coverage 82.42% 81.27% -1.15%
==========================================
Files 416 642 +226
Lines 28590 45806 +17216
Branches 0 4835 +4835
==========================================
+ Hits 23565 37229 +13664
- Misses 5025 7145 +2120
- Partials 0 1432 +1432 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR adds CSOM-backed CAML query support to IList to correctly return fields projected from joined lists (<Joins> / <ProjectedFields>), addressing the REST GetItems serialization limitation described in #1799. It introduces a CSOM request pipeline for List.GetItems(CamlQuery), materializes returned SP.ListItem JSON into the list’s Items collection, and exposes paging info for seamless page-by-page querying.
Changes:
- Added
IList.LoadItemsByCamlQueryViaCsomAsync/LoadItemsByCamlQueryViaCsomreturning a newICamlQueryCsomResult(items + paging info). - Implemented CSOM request/response handling for
List.GetItems(CamlQuery)includingCamlQueryparameter serialization. - Added a CSOM list-item materializer plus unit/integration tests and offline mock recordings for joins + projected fields + paging.
Reviewed changes
Copilot reviewed 30 out of 30 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/sdk/PnP.Core/Services/Core/CSOM/Requests/ListItems/GetItemsByCamlQueryResponse.cs | Defines the CSOM GetItems parsed response shape (items + paging info). |
| src/sdk/PnP.Core/Services/Core/CSOM/Requests/ListItems/GetItemsByCamlQueryRequest.cs | Builds CSOM List.GetItems(CamlQuery) request and parses the JSON response. |
| src/sdk/PnP.Core/Services/Core/CSOM/QueryAction/CamlQueryParameter.cs | Serializes SP.CamlQuery (including nested paging position) into CSOM XML. |
| src/sdk/PnP.Core/Model/SharePoint/Core/Public/IList.cs | Exposes the new CSOM-based CAML query methods on the public list API. |
| src/sdk/PnP.Core/Model/SharePoint/Core/Public/ICamlQueryCsomResult.cs | New public result contract for CSOM CAML query execution (items + paging info). |
| src/sdk/PnP.Core/Model/SharePoint/Core/Internal/List.cs | Implements the new IList APIs and wires them into Raw CSOM execution and materialization. |
| src/sdk/PnP.Core/Model/SharePoint/Core/Internal/CsomListItemsHandler.cs | Materializes CSOM SP.ListItem JSON objects into the list’s Items collection with typing. |
| src/sdk/PnP.Core/Model/SharePoint/Core/Internal/CamlQueryCsomResult.cs | Internal implementation of ICamlQueryCsomResult. |
| src/sdk/PnP.Core.Test/SharePoint/ListTests.cs | Adds integration test coverage for joins/projected fields and paging via the new CSOM method. |
| src/sdk/PnP.Core.Test/Services/Core/CSOM/Requests/GetItemsByCamlQueryRequestTests.cs | Adds request XML + response parsing unit tests for the new CSOM request. |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-2-00005.response.json | Recorded mock response: CSOM list items (page 2). |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-2-00004.response.json | Recorded mock response: list fields metadata. |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-2-00003.response.json | Recorded mock response: CSOM list items (page 1 + paging info). |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-2-00002.response.json | Recorded mock response: list metadata. |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-2-00001.response.json | Recorded mock response: site metadata. |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-2-00000.response.json | Recorded mock response: web regional settings metadata. |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00013.response.json | Recorded mock response: cleanup/no-content response. |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00012.response.json | Recorded mock response: cleanup/no-content response. |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00011.response.json | Recorded mock response: validate-update-item response (item 3). |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00010.response.json | Recorded mock response: validate-update-item response (item 2). |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00009.response.json | Recorded mock response: list fields metadata. |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00008.response.json | Recorded mock response: validate-update-item response (item 1). |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00007.response.json | Recorded mock response: field metadata (JoinLookup). |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00006.response.json | Recorded mock response: list fields metadata. |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00005.response.json | Recorded mock response: validate-update-item response (lookup item). |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00004.response.json | Recorded mock response: field metadata (ProjectedSourceText). |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00003.response.json | Recorded mock response: list creation metadata. |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00002.response.json | Recorded mock response: list creation metadata (lookup list). |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00001.response.json | Recorded mock response: site metadata. |
| src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00000.response.json | Recorded mock response: web regional settings metadata. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Adam-it
left a comment
There was a problem hiding this comment.
@jeppesc11 amaizing work 👏.
Checked locally ✅
I only left a few concerns about some edge cases I noticed that I think it's worth recheking before we merge.
I would also suggest we extend the docs https://github.com/pnp/pnpcore/blob/dev/docs/using-the-sdk/listitems-intro.md providing new examples how to use the added methods in this PR
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
Thanks for the thorough review @Adam-it 🙏 I've pushed a commit addressing the feedback. |
I added LoadItemsByCamlQueryViaCsomAsync / LoadItemsByCamlQueryViaCsom to IList.
These execute the CAML query via the CSOM List.GetItems(CamlQuery) method instead of the REST GetItems endpoint, so fields projected from joined lists (CAML Joins/ProjectedFields) are now returned as well, typed as IFieldLookupValue.
The loaded items are merged into the list's Items collection like the existing LoadItemsByCamlQuery methods, and the result also returns the PagingInfo from the CSOM ListItemCollectionPosition, which you can set on CamlQueryOptions.PagingInfo to load the next page without constructing the paging string manually.
🔗 Related Issue
Closes #1799