0

I use the following method to find List<File> on our SharePoint site:

    private async Task<List<File>> FindAsync(ClientContext clientContext, KeywordQuery keywordQuery)
    {
        ClientResult<ResultTableCollection> results = new SearchExecutor(clientContext)
            .ExecuteQuery(keywordQuery);
        await clientContext.ExecuteQueryAsync();

        List<File> files = new List<File>();
        foreach (IDictionary<string, object> resultRow in results.Value[0].ResultRows)
        {
            File file = GetFromPath(clientContext, resultRow["Path"].ToString());
            files.Add(file);
        }
        return files;
    }

    private File GetFromPath(ClientContext clientContext, string path)
    {
        Web web = clientContext.Web;
        List list = web.GetListByTitle(_sharePointConfig.DocumentsRoot);

        int parameterIndex = path.IndexOf('?');
        string query = parameterIndex >= 0 
            ? path[parameterIndex..] 
            : "";
        System.Collections.Specialized.NameValueCollection queryParts = HttpUtility.ParseQueryString(query);
        string id = queryParts.Get("ID");
        ListItem item = list.GetItemById(id);
        return item.File;                
    }

This works as expected on a Sharepoint site we created specifically so I would not be testing against production data.

However, when I then swapped the siteUrl to reference the production site -- hosted on exactly the same instance of SharePoint Online, with the same SharePoint online subdomain -- this failed.

Whereas the developer site would return Urls like

https://example.sharepoint.com/sites/DevelopementTestingSite/Shared Documents/Forms/DispForm.aspx?ID=43

on the production site, I get back Urls like:

"https://example.sharepoint.com/sites/Mietkundenseite2/Freigegebene Dokumente/Alle Mietantrag Enpal/von Angenommen ab Mai.2019/20190605_Weiss_11_Mietantrag.pdf"

Because this URL does not contain the ID, the method fails.

Is there a way I can ensure that I always get back the format with the Id?

Alternatively, is there a way I can use the production format to get the corresponding File value?

0

This is really more of a work-around, and arguably a better solution, than an answer to the actual question:

    private async Task<List<File>> FindAsync(ClientContext clientContext, KeywordQuery keywordQuery)
    {
        ClientResult<ResultTableCollection> results = new SearchExecutor(clientContext)
            .ExecuteQuery(keywordQuery);
        await clientContext.ExecuteQueryAsync();

        List<File> files = new List<File>();
        foreach (IDictionary<string, object> resultRow in results.Value[0].ResultRows)
        {
            Guid uniqueId = Guid.Parse(resultRow["UniqueId"].ToString());
            files.Add(GetByUniqueId(clientContext, uniqueId));
        }
        return files;
    }

    private File GetByUniqueId(ClientContext clientContext, Guid uniqueId)
    {
        File file = clientContext.Web.GetFileById(uniqueId);
        clientContext.Load(file, f => f.Name);
        clientContext.ExecuteQuery();
        return file;                
    }
1
  • While I no longer need the answer to my original question, for the sake of curiousity -- and because I can't accept my own answer yet anyway -- I leave this question open (for now). – Brian Kessler Nov 27 '20 at 10:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.