Initial commit
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.SharePoint.Client;
|
||||
using SharepointToolbox.Web.Core.Models;
|
||||
|
||||
namespace SharepointToolbox.Web.Core.Helpers;
|
||||
|
||||
public static class SharePointPaginationHelper
|
||||
{
|
||||
private const int DefaultRowLimit = 5000;
|
||||
|
||||
public static async IAsyncEnumerable<ListItem> GetAllItemsAsync(
|
||||
ClientContext ctx,
|
||||
List list,
|
||||
CamlQuery? baseQuery = null,
|
||||
[EnumeratorCancellation] CancellationToken ct = default)
|
||||
{
|
||||
var query = baseQuery ?? CamlQuery.CreateAllItemsQuery();
|
||||
query.ViewXml = BuildPagedViewXml(query.ViewXml, DefaultRowLimit);
|
||||
query.ListItemCollectionPosition = null;
|
||||
|
||||
do
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
var items = list.GetItems(query);
|
||||
ctx.Load(items);
|
||||
await ctx.ExecuteQueryAsync();
|
||||
foreach (var item in items) yield return item;
|
||||
query.ListItemCollectionPosition = items.ListItemCollectionPosition;
|
||||
}
|
||||
while (query.ListItemCollectionPosition != null);
|
||||
}
|
||||
|
||||
public static async IAsyncEnumerable<ListItem> GetItemsInFolderAsync(
|
||||
ClientContext ctx,
|
||||
List list,
|
||||
string folderServerRelativeUrl,
|
||||
bool recursive,
|
||||
string[]? viewFields = null,
|
||||
[EnumeratorCancellation] CancellationToken ct = default)
|
||||
{
|
||||
var fields = viewFields ?? new[]
|
||||
{
|
||||
"FSObjType", "FileRef", "FileLeafRef", "FileDirRef", "File_x0020_Size"
|
||||
};
|
||||
var viewFieldsXml = string.Join(string.Empty, fields.Select(f => $"<FieldRef Name='{f}' />"));
|
||||
var scope = recursive ? " Scope='RecursiveAll'" : string.Empty;
|
||||
var viewXml =
|
||||
$"<View{scope}><Query></Query>" +
|
||||
$"<ViewFields>{viewFieldsXml}</ViewFields>" +
|
||||
$"<RowLimit Paged='TRUE'>{DefaultRowLimit}</RowLimit></View>";
|
||||
|
||||
var query = new CamlQuery
|
||||
{
|
||||
ViewXml = viewXml,
|
||||
FolderServerRelativeUrl = folderServerRelativeUrl,
|
||||
ListItemCollectionPosition = null
|
||||
};
|
||||
|
||||
do
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
var items = list.GetItems(query);
|
||||
ctx.Load(items);
|
||||
await ctx.ExecuteQueryAsync();
|
||||
foreach (var item in items) yield return item;
|
||||
query.ListItemCollectionPosition = items.ListItemCollectionPosition;
|
||||
}
|
||||
while (query.ListItemCollectionPosition != null);
|
||||
}
|
||||
|
||||
internal static string BuildPagedViewXml(string? existingXml, int rowLimit)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(existingXml))
|
||||
return $"<View><RowLimit Paged='TRUE'>{rowLimit}</RowLimit></View>";
|
||||
if (System.Text.RegularExpressions.Regex.IsMatch(
|
||||
existingXml, @"<RowLimit[^>]*>\d+</RowLimit>",
|
||||
System.Text.RegularExpressions.RegexOptions.IgnoreCase))
|
||||
{
|
||||
return System.Text.RegularExpressions.Regex.Replace(
|
||||
existingXml, @"<RowLimit[^>]*>\d+</RowLimit>",
|
||||
$"<RowLimit Paged='TRUE'>{rowLimit}</RowLimit>",
|
||||
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
|
||||
}
|
||||
return existingXml.Replace("</View>",
|
||||
$"<RowLimit Paged='TRUE'>{rowLimit}</RowLimit></View>",
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user