0

I am trying to pull some documents from Sharepoint using the CSDOM Microsoft.Sharepoint.Client SDK.

I have a basic query set up like this:

let uri = @"XXXXXX"
let userName = XXXXXX
let password = XXXXXX
let networkCredential = new NetworkCredential(userName, password)
let context = new ClientContext(uri)
context.Credentials <- networkCredential
let list = context.Web.Lists.GetByTitle("XXXXXX")
let listItemCollection = list.GetItems(CamlQuery.CreateAllItemsQuery())
context.Load(listItemCollection)
context.ExecuteQuery()

I am getting this error message on the load method

error FS0193: internal error: GenericArguments[0], 'Microsoft.SharePoint.Client.ListItemCollection', on 'Void Load[T](T, System.Linq.Expressions.Expression1[System.Func2[T,System.Object]][])' violates the constraint of type 'T'.

I think I have to pass in the linq expression also? This seems like a lot of unneeded steps as all I want to do is get a list of documents from a folder to iterate.

Anyone have any alternative code?

Jamie Dixon
  • 4,204
  • 4
  • 25
  • 47
  • Note that context.Load(listItemCollection) works fine in C# without a second parameter – Jamie Dixon Mar 24 '21 at 16:50
  • I'm trying to reproduce this using my company's Sharepoint site, but getting a 403 (Forbidden) error. Do I need special privileges? The URL I'm trying looks like "https://mycompany.sharepoint.com/". – Brian Berns Mar 24 '21 at 23:25
  • I figured out how to connect. Am trying to debug the issue now. – Brian Berns Mar 25 '21 at 00:12

1 Answers1

1

OK, I was able to get this to work using this answer. Here's my working code:

open System
open System.Linq.Expressions

type Expr = 
    static member Quote(e:Expression<System.Func<_, _>>) = e

// ...
// Authentication logic goes here. Personally, I had to use
// SharePointOnlineCredentials instead of NetworkCredential.
// ...

let items =
    let list = context.Web.Lists.GetByTitle("Documents")
    list.GetItems(CamlQuery())
let getDisplayName =
    Expr.Quote(
        fun (item : ListItem) ->
            item.DisplayName :> obj)
context.Load(
    items,
    fun (items : ListItemCollection) ->
        items.Include(getDisplayName) :> obj)
context.ExecuteQuery()
for item in items do
    printfn "%s" item.DisplayName

It ain't pretty, but it gets the job done.

Brian Berns
  • 15,499
  • 2
  • 30
  • 40