web-dev-qa-db-ja.com

c#-Microsoft Graph API-フォルダーが存在するかどうかを確認する

私は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を取得するかどうかを確認するにはどうすればよいですか?

10
user979331

グラフ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://docs.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>のようなことをしたり、ファイルの種類を調べたりできます(特定のケースでは役に立たないと思いますが、完全を期すために言及します) )

4
timur

フォルダー名のフォルダーを取得するには:

グラフAPIを呼び出す Reference1Reference2/me/drive/items/{item-id}:/path/to/file

つまり、/drive/items/id-of-folder-I-am-putting-this-into:/{folderName}

  • フォルダーが存在する場合、それは driveItem 応答を返します。

  • フォルダが存在しない場合は、404(NotFound)を返します

ここで、フォルダーの作成中に、フォルダーが既に存在する場合、呼び出しを失敗させるために、次のように追加のデータを設定してみてください 参照

    AdditionalData = new Dictionary<string, object>
    {
        { "@Microsoft.graph.conflictBehavior", "fail" }
    }
  • フォルダーが存在する場合、これは409 Conflictを返します
1
Matt.G

クエリベースのアプローチは、この点で検討できます。設計上 DriveItem.name property はフォルダー内で一意です。次のクエリは、ドライブアイテムが存在するかどうかを確認するために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();

提供されたエンドポイントが与えられた場合、フローは次のステップで構成されます。

  • 指定された名前のフォルダがすでに存在するかどうかを判断するリクエストを送信する
  • フォルダーが見つからなかった場合は2番目を送信します(または既存のフォルダーを返します)

これが更新された例です

//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);

  }
1

コンテナで search request を発行します。

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);
1
Paul Schaeflein