我在MS Graph v5.42.0中使用寻呼来获取消息.在下面的c#示例中,我希望从包含70条消息的邮件文件夹中获取50条消息.正如预期的那样,第一页返回30条消息.对于第二页,我将页面大小更改为20(顶部).但在获取第二个页面时,更改页面大小似乎没有影响,因为会返回30条消息.使用分页时更改页面大小是不可能的吗?

int maxItemSize = 50;
int pageSize = 30;
if (maxItemSize <= pageSize)
    pageSize = maxItemSize;

string itemSearchFilter = GetItemFilters(messageClasses, onlyMailsWithAttachments,
    ignoredDomains, archiveSize, archiveDate, archiveAge, setFilterIgnoreSignedItems, setFilterNotKdxArchived, setFilterKdxArchived);

string expandValue = string.Format("singleValueExtendedProperties($filter = id eq '{0}' or id eq '{1}' or id eq '{2}' or id eq '{3}' or id eq '{4}')",
    MessageClassPropertyID1, DisplayToPropertyID1, DisplayCcPropertyID1, NativeBodyPropertyID, MessageSizePropertyID1);

List<Message> messages = new List<Message>();

var messagesResponse = await GraphServiceClient
    .Users[CurrentMailBoxAddress]
    .MailFolders[FolderId]
    .Messages
    .GetAsync((requestConfiguration) =>
    {
        requestConfiguration.QueryParameters.Top = pageSize;
        requestConfiguration.QueryParameters.Expand = new string[] { expandValue };
        requestConfiguration.QueryParameters.Filter = itemSearchFilter;
    });

while (messagesResponse.Value != null)
{
    messages.AddRange(messagesResponse.Value);

    if (messages.Count() >= maxItemSize)
        break;
    else
    {
        int messagesToBeRetrieved = maxItemSize - messages.Count();
        if (messagesToBeRetrieved <= pageSize)
        {
            // Resets the page size for the last request
            pageSize = messagesToBeRetrieved;
        }

        // If OdataNextLink has a value, there is another page
        if (!string.IsNullOrEmpty(messagesResponse.OdataNextLink))
        {
            messagesResponse = await GraphServiceClient
                .Users[CurrentMailBoxAddress]
                .MailFolders[FolderId]
                .Messages
                .WithUrl(messagesResponse.OdataNextLink)
                .GetAsync((requestConfiguration) =>
                {
                    requestConfiguration.QueryParameters.Top = pageSize;
                    requestConfiguration.QueryParameters.Expand = new string[] { expandValue };
                    requestConfiguration.QueryParameters.Filter = itemSearchFilter;
                });
        }
        else
        {
            // No more results, exit loop
            break;
        }
    }
}

推荐答案

正如方法WithUrl的注释所述

使用此方法意味着忽略任何其他路径或查询参数.

这意味着在GetAsync(...)中指定的每个查询参数都被忽略.

OdataNextLink包含第一个请求中指定的查询参数,带有额外的参数$skip

https://graph.microsoft.com/v1.0/users/{user_id}/mailFolders/{folder_id}/messages?$filter=xxx&$expand=xxx&$top=30&$skip=30

在此基础上,我将go 掉WithUrl,并为下一个请求手动指定所有查询参数

int maxItemSize = 50;
int pageSize = 30;
// how many items should be skipped
int skipItems = 0;
if (maxItemSize <= pageSize)
    pageSize = maxItemSize;

string itemSearchFilter = GetItemFilters(messageClasses, onlyMailsWithAttachments,
    ignoredDomains, archiveSize, archiveDate, archiveAge, setFilterIgnoreSignedItems, setFilterNotKdxArchived, setFilterKdxArchived);

string expandValue = string.Format("singleValueExtendedProperties($filter = id eq '{0}' or id eq '{1}' or id eq '{2}' or id eq '{3}' or id eq '{4}')",
    MessageClassPropertyID1, DisplayToPropertyID1, DisplayCcPropertyID1, NativeBodyPropertyID, MessageSizePropertyID1);

List<Message> messages = new List<Message>();

var messagesResponse = await GraphServiceClient
    .Users[CurrentMailBoxAddress]
    .MailFolders[FolderId]
    .Messages
    .GetAsync((requestConfiguration) =>
    {
        requestConfiguration.QueryParameters.Top = pageSize;
        requestConfiguration.QueryParameters.Expand = new string[] { expandValue };
        requestConfiguration.QueryParameters.Filter = itemSearchFilter;
    });

while (messagesResponse.Value != null)
{
    messages.AddRange(messagesResponse.Value);

    if (messages.Count() >= maxItemSize)
        break;
    else
    {
        int messagesToBeRetrieved = maxItemSize - messages.Count();
        if (messagesToBeRetrieved <= pageSize)
        {
            // increment number of items to be skipped
            skipItems += pageSize;
            // Resets the page size for the last request
            pageSize = messagesToBeRetrieved;
        }

        // If OdataNextLink has a value, there is another page
        if (!string.IsNullOrEmpty(messagesResponse.OdataNextLink))
        {
            messagesResponse = await GraphServiceClient
                .Users[CurrentMailBoxAddress]
                .MailFolders[FolderId]
                .Messages
                // WithUrl removed
                .GetAsync((requestConfiguration) =>
                {
                    // specify skip parameter
                    requestConfiguration.QueryParameters.Skip = skipItems;
                    requestConfiguration.QueryParameters.Top = pageSize;
                    requestConfiguration.QueryParameters.Expand = new string[] { expandValue };
                    requestConfiguration.QueryParameters.Filter = itemSearchFilter;
                });
        }
        else
        {
            // No more results, exit loop
            break;
        }
    }
}

Csharp相关问答推荐

FromServices不使用WebAppliationFactory程序>

如何从泛型方法返回一个可为空的T,其中T:notnull?

以自动方式注销Azure身份应用程序

处理. netstandard2.0项目中HttpClient.SslProtocol的PlatformNotSupportedException问题""

Entity Framework Core 8 dbcontext—无法以多对多关系添加某些行'

`Task`只有在C#中等待时才会运行吗?

如果属性名为xyz,我需要使用System.Text.Json修改字符串类型的值""<>

Polly使用泛型重试和重试包装函数

由于POST中的应用程序/JWT,出现不支持的内容类型异常

如何将此方法参数化并使其更灵活?

在.NET MAUI.NET 8中如何防止按钮点击时出现灰色反馈

当索引和外键是不同的数据类型时,如何设置导航属性?

C#Null判断处理失败

在DoubleClick上交换DataGridViewImageColumn的图像和工具提示

Azure函数-在外部启动类中生成配置时出错

Postgres ENUM类型在第一次运行时对Dapper不可见

在扩展方法中,IEnumerable<;T>;不会转换为IEumerable<;T&>

RCL在毛伊岛应用程序和Blazor服务器应用程序.Net 8.0中使用页面

C#定时器回调对象上下文?

阻止CLR释放已封送的双字符指针的内存?