Search code examples
c#azuresharepointmicrosoft-graph-apimicrosoft-graph-sdks

Search driveItem with query of Document-ID


My goal is to read out the driveItemId from the Document-ID.

Document-ID is a unique SharePoint column that is given to every file in the SharePoint library.

I tried using this method below to get a driveItem (by its driveItemId) using search with a query:

public async Task<string> GetDriveItemIdAsync(string driveId, string docId)
{
    try
    {
        var query = $"Dokument-ID:{docId}";

        var results = await _graphClient.Drives[driveId].SearchWithQ(query).GetAsSearchWithQGetResponseAsync();

        if (results.Value.Count == 1)
        {
            _logger.Info($"Found one document with documentId '{docId}' in drive '{driveId}'.");
            return results.Value.FirstOrDefault().Id;
        }
        else if (results.Value.Count == 0)
        {
            _logger.Info($"No document with documentId '{docId}' found in drive '{driveId}'.");
            throw new Exception($"No document with documentId '{docId}' found in drive '{driveId}'.");
        }
        else
        {
            var driveItemId = results.Value.FirstOrDefault().Id;
            var message = "Dokumente: \n";

            foreach (var item in results.Value)
            {
                message += $"Name: {item.Name}, Id: {item.Id}\n";
            }

            _logger.Error($"More than one document with documentId '{docId}' found in drive '{driveId}'. Returning the first item with driveItemId == '{driveItemId}' \n{message}");
            MessageBox.Show($"Mehr als ein Dokument mit der DocumentId '{docId}' in Laufwerk '{driveId}' gefunden. Melden Sie sich sofort bei der IT und zeigen Sie diese Fehlermeldung. \n{message}", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return driveItemId;
        }
    }
    catch (ServiceException ex)
    {
        _logger.Error($"Error while trying to get last version of item with documentId '{docId}' in drive '{driveId}'. Exception: '{ex}'");
        throw;
    }
}

I haven't quite understood query yet, with certain documentID inputs I get no item back at all, and with others I get much more than just one item back, even though the documentID column doesn't match at all.

It is behaving very strangely, probably because my query is not yet correct.

Thanks for your help, I'm also open for a better solution for getting the driveItemId by DocumentID in a SharePoint library.


Edit:

Using filter could be a solution too, but i think the anwser in this post is no longer valid, couldnt find anything in the documentation about it.


Solution

  • I would use v1.0/search/query endpoint to find listItem by documentId. What I remember, you actually need listItem id. What's important documentId is related to listItem, not a driveItem

    using Microsoft.Graph.Search.Query;
    using Microsoft.Graph.Models;
    
    var documentId = "7NDKNNDUE4VT-1387038990-1"
    var requestBody = new QueryPostRequestBody
    {
        Requests = new List<SearchRequest>
        {
            new SearchRequest
            {
                EntityTypes = new List<EntityType?>
                {
                    EntityType.ListItem,
                },
                Query = new SearchQuery
                {
                    QueryString = $"dlcDocId:{documentId}",
                },
            },
        },
    };
    
    var result = await graphClient.Search.Query.PostAsQueryPostResponseAsync(requestBody);
    
    if (result.Value[0].HitsContainers[0].Hits[0].Resource is ListItem listItem)
    {
        var siteId = listItem.ParentReference.SiteId;
        var listId = listItem.SharepointIds.ListId;
        var listItemId = listItem.SharepointIds.ListItemId;
    }
    

    If you want to limit searching to a specific site and document library:

    "queryString": "dlcDocId:7NDKNNDUE4VT-1387038990-1 AND path:\"https://contoso.sharepoint.com/sites/{site_name}/{library_name}\""