web-dev-qa-db-fra.com

c # - API Microsoft Graph - Vérifier si le dossier existe

J'utilise l'API Microsoft Graph et je crée un dossier comme ceci:

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

Ma question est de savoir comment vérifier si ce dossier existe et s'il obtient l'ID du dossier?

10
user979331

L'API graphique fournit une fonction de recherche , que vous pouvez utiliser pour savoir si un élément existe. Vous avez soit la possibilité d'exécuter la recherche d'abord, puis de créer un élément si rien n'a été trouvé, ou vous pouvez faire comme @ Matt.G suggère et jouer autour de nameAlreadyExists exception:

        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
            }
        }

Le texte de requête utilisé pour rechercher des éléments. Les valeurs peuvent être mises en correspondance dans plusieurs champs, notamment le nom de fichier, les métadonnées et le contenu du fichier.

vous pouvez jouer avec requête de recherche et faire des choses comme filename=<yourName> ou potentiellement examiner les types de fichiers (ce qui, je suppose, ne va pas aider dans votre cas particulier, mais je le mentionnerais par souci d'exhaustivité)

4
timur

Pour obtenir le dossier avec le nom du dossier:

api du graphique d'appel Reference1Reference2 : /me/drive/items/{item-id}:/path/to/file

c'est à dire. /drive/items/id-of-folder-I-am-putting-this-into:/{folderName}

  • Si le dossier existe, il renvoie une réponse driveItem , qui a l'id

  • Si le dossier n'existe pas, il renvoie un 404 (NotFound)

Maintenant, lors de la création d'un dossier, si le dossier existe déjà, afin d'échouer l'appel, essayez de définir des données supplémentaires comme suit Référence :

    AdditionalData = new Dictionary<string, object>
    {
        { "@Microsoft.graph.conflictBehavior", "fail" }
    }
  • Cela retournera un conflit 409, si le dossier existe
1
Matt.G

Une approche basée sur les requêtes pourrait être envisagée à cet égard. Étant donné que par conception DriveItem.name property est unique dans un dossier, la requête suivante montre comment filtrer driveItem par nom afin de déterminer si un élément de lecteur existe:

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

qui pourrait être représenté en C # comme ceci:

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

Étant donné le point final fourni, le flux peut comprendre les étapes suivantes:

  • soumettre une demande pour déterminer si un dossier portant un nom donné existe déjà
  • soumettre un second dossier si aucun dossier n'a été trouvé (ou renvoyer un dossier existant)

Exemple

Voici un exemple mis à jour

//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
Vadim Gremyachev

Émettez un demande de recherche sur le conteneur.

var existingItems = await graphServiceClient.Me.Drive
                          .Items["id-of-folder-I-am-putting-this-into"]
                          .Search("search")
                          .Request().GetAsync();

Vous devez ensuite itérer la collection existingItems ( possible comprenant plusieurs pages ) pour déterminer si l'élément existe.

Vous ne spécifiez pas les critères pour déterminer si un élément existe. En supposant que vous vouliez dire par votre nom, vous pourriez:

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