1
votes

I am trying to use SharePoint client framework to execute a search, using the portable dll's from a Windows app.

Using Fiddler I can see that my search is executed, and returns a JSON collection of metadata and search results. This is identical to the result from the non-portable CSOM.

When CSOM tries to map the result to it's data objects I get the following exception:

Unable to cast object of type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]' to type 'Microsoft.SharePoint.Client.Search.Query.ResultTableCollection'.

This exception occurs inside CSOM (portable). Non-portable CSOM runs without exception, and returns the expected result.

The code I am running to get this exception is:

var query = new KeywordQuery(ctx);
query.QueryText = "something";
var executor = new SearchExecutor(ctx);
var results = executor.ExecuteQuery(query);
await ctx.ExecuteQueryAsync();

In the above, ctx is a ClientContext that has already been authenticated. Other requests, such as getting a specific list, works as expected.

I am referencing the following dll's from c:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI:

  • Microsoft.SharePoint.Client.Portable.dll
  • Microsoft.SharePoint.Client.Runtime.Portable.dll
  • Microsoft.SharePoint.Client.Runtime.WindowsStore.dll
  • Microsoft.SharePoint.Client.Search.Portable.dll

My question is.

How do I solve this, so that I can use CSOM to run search queries from a Windows Store app?

UPDATE: I added the following after authenticating the ClientContext:

ctx.ExecutingWebRequest += (s, e) =>
    e.WebRequest.Headers["Accept-Encoding"] = "gzip, deflate";

This solved the immediate problem, but introduced a new one. I am now getting a System.FormatException:

Not well formatted JSON stream.

Since the JSON from portable and non-portable CSOM is the same, there should not be a parsing error in one CSOM and not the other.

2

2 Answers

0
votes

What I can identify from your exception is that casting of execute query result creates problem here.

Use below code to cast execute query result

ResultTable rtSharePointSearchResult = new ResultTable();
KeywordQuery query = new KeywordQuery(clientContext);
query.QueryText = "Keywords";
query.TrimDuplicates = false;
SearchExecutor searchExecutor = new SearchExecutor(clientContext);
ClientResult<ResultTableCollection> results = searchExecutor.ExecuteQuery(query);
clientContext.ExecuteQuery();
rtSharePointSearchResult = results.Value[0];
0
votes

Notice that the first post uses ctx.ExecuteQueryAsync but the "answer" uses ctx.ExecuteQuery.

The bug is in the portable class library (that the first post uses) but this works in the non-portable version (the second post).

Cheers, Paul