检查Graph API文件夹是否存在。

12

我正在使用Microsoft Graph API,并且像这样创建文件夹:

var driveItem = new DriveItem
{
    Name = Customer_Name.Text + Customer_LName.Text,
    Folder = new Folder
    {
    },
    AdditionalData = new Dictionary<string, object>()
    {
        {"@microsoft.graph.conflictBehavior","rename"}
    }
};

var newFolder = await App.GraphClient
  .Me
  .Drive
  .Items["id-of-folder-I-am-putting-this-into"]
  .Children
  .Request()
  .AddAsync(driveItem);

我的问题是如何检查该文件夹是否存在,如果存在,则获取该文件夹的id?

7个回答

5

Graph API提供了搜索功能,您可以利用它来查找项目是否存在。您可以选择先运行搜索,然后在找不到任何内容时创建一个项目,或者像@Matt.G建议的那样玩弄nameAlreadyExists异常:

        var driveItem = new DriveItem
        {
            Name = Customer_Name.Text + Customer_LName.Text,
            Folder = new Folder
            {
            },
            AdditionalData = new Dictionary<string, object>()
            {
                {"@microsoft.graph.conflictBehavior","fail"}
            }
        };

        try
        {
            driveItem = await graphserviceClient
                .Me
                .Drive.Root.Children
                .Items["id-of-folder-I-am-putting-this-into"]
                .Children
                .Request()
                .AddAsync(driveItem);
        }
        catch (ServiceException exception)
        {
            if (exception.StatusCode == HttpStatusCode.Conflict && exception.Error.Code == "nameAlreadyExists")
            {
                var newFolder = await graphserviceClient
                    .Me
                    .Drive.Root.Children
                    .Items["id-of-folder-I-am-putting-this-into"]
                    .Search(driveItem.Name) // the API lets us run searches https://learn.microsoft.com/en-us/graph/api/driveitem-search?view=graph-rest-1.0&tabs=csharp
                    .Request()
                    .GetAsync();
                // since the search is likely to return more results we should filter it further
                driveItem = newFolder.FirstOrDefault(f => f.Folder != null && f.Name == driveItem.Name); // Just to ensure we're finding a folder, not a file with this name
                Console.WriteLine(driveItem?.Id); // your ID here
            }
            else
            {
                Console.WriteLine("Other ServiceException");
                throw;// handle this
            }
        }

查询文本用于搜索项目。值可以匹配多个字段,包括文件名、元数据和文件内容。

您可以使用搜索查询并执行诸如filename=<yourName>之类的操作,或者可能检查文件类型(我猜这对您的特定情况没有帮助,但为了完整起见,我还是要提一下)


5

获取具有文件夹名称的文件夹:

调用图形API 参考1 参考2/me/drive/items/{item-id}:/path/to/file

例如:/drive/items/id-of-folder-I-am-putting-this-into:/{folderName}

  • 如果该文件夹存在,则返回一个driveItem响应,其中包含id

  • 如果该文件夹不存在,则返回404(未找到)

现在,在创建文件夹时,如果该文件夹已经存在,为了使调用失败,请尝试按照以下方式设置附加数据参考

    AdditionalData = new Dictionary<string, object>
    {
        { "@microsoft.graph.conflictBehavior", "fail" }
    }
  • 如果文件夹已存在,这将返回一个409冲突错误

但是我怎么才能获得现有文件夹的 ID 呢? - user979331

4

在这方面可以考虑采用基于查询的方法。由于根据设计,DriveItem.name属性在文件夹中是唯一的,以下查询演示了如何通过名称过滤driveItem以确定驱动器项是否存在:

https://graph.microsoft.com/v1.0/me/drive/items/{parent-item-id}/children?$filter=name eq '{folder-name}'

在C#中可以表示为:

var items = await graphClient
            .Me
            .Drive
            .Items[parentFolderId]
            .Children
            .Request()
            .Filter($"name eq '{folderName}'")
            .GetAsync();

根据提供的端点,流程可能包括以下步骤:

  • 提交请求以确定是否已经存在一个给定名称的文件夹
  • 如果未找到文件夹,则提交第二个请求(或返回一个已存在的文件夹)

例子

下面是一个更新后的例子

//1.ensure drive item already exists (filtering by name) 
var items = await graphClient
            .Me
            .Drive
            .Items[parentFolderId]
            .Children
            .Request()
            .Filter($"name eq '{folderName}'")
            .GetAsync();



if (items.Count > 0) //found existing item (folder facet)
{
     Console.WriteLine(items[0].Id);  //<- gives an existing DriveItem Id (folder facet)  
}
else
{
     //2. create a folder facet
     var driveItem = new DriveItem
     {
         Name = folderName,
         Folder = new Folder
         {
         },
         AdditionalData = new Dictionary<string, object>()
         {
                    {"@microsoft.graph.conflictBehavior","rename"}
         }
     };

     var newFolder = await graphClient
                .Me
                .Drive
                .Items[parentFolderId]
                .Children
                .Request()
                .AddAsync(driveItem);

  }

0

微软图表中有一些有用的API,可以搜索特定驱动器中的文件夹:

  1. 检查根目录下名称为 folder_name_to_be_search 的文件夹:

    方法GET

    必需的标头

    Authorization: Bearer <access_token>
    

    API URL:

    https://graph.microsoft.com/v1.0/drives/<your-drive-id>/root:/<folder_name_to_be_search>
    
  2. 检查根目录下任何父文件夹中是否存在名称为 folder_name_to_be_search 的文件夹:

    方法GET

    必需的标头

    Authorization: Bearer <access_token>
    

    API URL:

    https://graph.microsoft.com/v1.0/drives/<your-drive-id>/items/<parent-folder-id>:/<folder_name_to_be_search>
    
  3. 获取所有驱动器子项的 API:

    方法GET

    必需的标头

    Authorization: Bearer <access_token>
    

    API URL:

    https://graph.microsoft.com/v1.0/drive/root/children
    
  4. 获取驱动器中父文件夹内的子项的 API:

    方法GET

    必需的标头

    Authorization: Bearer <access_token>
    

    API URL:

    https://graph.microsoft.com/v1.0/drives/<your-drive-id>/items/<parent-folder-id>/children
    

0

我的实现使用了应用程序级别的图形API访问。

创建一个带有子项的驱动器项目结构,以表示您的文件树,然后沿着实际的图形API响应遍历它:

public class DriveItem
{
    public string ItemID { get; set; }
    public string Name { get; set; }
    public string URL { get; set; }

    public List<DriveItem> Children { get; set; }
}

public async Task<bool> DirectoryExists(DriveItemRequest request)
{
    if (!string.IsNullOrEmpty(request.SiteID) &&
        !string.IsNullOrEmpty(request.DriveID) &&
        request.Root != null)
    {
        var currentFolder = await _client.Sites[request.SiteID].Drives[request.DriveID]
            .Root.Children.Request().Filter($"name eq '{request.Root.Name}'").GetAsync();

        if (currentFolder.Count > 0)
        {
            var currentItem = request.Root;
            while (currentFolder.Count > 0 && currentItem.Children != null)
            {
                // navigate to child
                currentItem = currentItem.Children[0];

                // traverse folder structure
                currentFolder = await _client.Sites[request.SiteID].Drives[request.DriveID]
                    .Items[currentFolder[0].Id].Children.Request()
                    .Filter($"name eq '{currentItem.Name}'").GetAsync();
            }

            return currentFolder.Count > 0 ? true : false;
        }
    }
            
    return false;
}

0
在该容器上发出一个搜索请求
var existingItems = await graphServiceClient.Me.Drive
                          .Items["id-of-folder-I-am-putting-this-into"]
                          .Search("search")
                          .Request().GetAsync();

然后必须迭代existingItems集合(可能包含多个页面),以确定该项是否存在。

您没有指定确定项目是否存在的标准。假设您的意思是按名称,您可以:

var exists = existingItems.CurrentPage
               .Any(i => i.Name.Equals(Customer_Name.Text + Customer_LName.Text);

是的,但我如何从已存在的获取ID? - user979331
请使用Where()、FirstOrDefault()或适当的表达式。 - Paul Schaeflein

-1

您可以通过调用以下内容来获取文件夹的ID:https://graph.microsoft.com/v1.0/me/drive/root/children。它将为您提供驱动器中的所有项目。如果您还没有文件夹ID,您可以使用名称或其他属性来过滤结果以获取文件夹ID。

public static bool isPropertyExist (dynamic d)
{
  try {
       string check = d.folder.childCount;
       return true;
  } catch {
       return false;
  }
}
var newFolder = await {https://graph.microsoft.com/v1.0/me/drive/items/{itemID}}


if (isPropertyExist(newFolder))
{
  //Your code goes here.
}

如果驱动器中的项目类型是文件夹,则会获取一个folder 属性。您可以检查此属性是否存在,如果存在则运行您的代码以添加该项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接