1
votes

Question

How do I read file content of the specific version?

What I have tried

  1. I've tried:

    var webClient = new WebClient() {Credentials = Context.Credentials })
    webClient.DownloadString($"{Context.Url}{fileVersion.Url}");
    

    but the Credentials is null. I've tried also UseDefaultCredential = true, but in both cases I'm getting 403 forbidden:

    System.Net.WebException: 'The remote server returned an error: (403) Forbidden.'

  2. I've also tried:

    File.OpenBinaryDirect(sharepoint.Context, fileVersion.Url)
    //fileVersion.Url == "_vti_history/512/ListName/filename.xml"
    
    > Specified argument was out of the range of valid values.
    > Parameter name: serverRelativeUrl
    
  3. and also starting with /:

     File.OpenBinaryDirect(sharepoint.Context, "/" + fileVersion.Url)
    

    System.Net.WebException: 'The remote server returned an error: (404) Not Found.'

How do I create ClientContext:

I use sharepoint PnP to create and authenticate my ClientContext:

var authentication = new OfficeDevPnP.Core.AuthenticationManager();
Context = authentication.GetWebLoginClientContext(siteUrl);

I'm able to retrieve list of FileVersion:

var items = list.GetItems(camlQuery);
Context.Load(items);
Context.ExecuteQuery();
foreach (ListItem item in items)
{
    sharepoint.Context.Load(item.Versions);
    sharepoint.Context.Load(item.File.Versions);
    sharepoint.Context.Load(item.File);

    sharepoint.Context.ExecuteQuery();

    foreach (var fileVersion in item.File.Versions)
    {
         ReadFile(fileVersion);
    }
}

here are versions of my libraries:

<package id="Microsoft.SharePointOnline.CSOM" version="16.1.7018.1200" targetFramework="net461" />
<package id="SharePointPnP.IdentityModel.Extensions" version="1.2.2" targetFramework="net461" />
<package id="SharePointPnPCoreOnline" version="2.19.1710.2" targetFramework="net461" />
1

1 Answers

1
votes

I've hacked the webclient authentication by stealing cookies from ClientContext:

var authentication = new OfficeDevPnP.Core.AuthenticationManager();
context = authentication.GetWebLoginClientContext(siteUrl);
webClient = new WebClient();
context.ExecutingWebRequest += StealCookieOnExecutingWebRequest;
void StealCookieOnExecutingWebRequest(object sender, WebRequestEventArgs e)
{
    var cookies = e.WebRequestExecutor.WebRequest.CookieContainer;
    webClient.Headers[HttpRequestHeader.Cookie] = cookies.GetCookieHeader(new Uri(SiteUrl));
    context.ExecutingWebRequest -= StealCookieOnExecutingWebRequest;
}

I will not mark this as answer yet, since there might be better solution.