Calling BCS FindFiltered method on BCS from Client Object Model throws An exception of type ‘Microsoft.SharePoint.Client.ServerException’ occurred in Microsoft.SharePoint.Client.Runtime.dll but was not handled in user code


Recently I cam across an interesting issue from a customer where customer was calling the FindFiltered method of external content type to get filtered items.

Following is the sample code that calls the FindFiltered method.

            string readListInstanceName = ConfigurationManager.AppSettings["method"];
            Microsoft.BusinessData.MetadataModel.Entity entity = clientContext.Web.GetEntity(ConfigurationManager.AppSettings["namespace"], ConfigurationManager.AppSettings["name"]);
            Microsoft.BusinessData.MetadataModel.LobSystem lobSystem = entity.GetLobSystem();
            Microsoft.BusinessData.MetadataModel.Collections.LobSystemInstanceCollection lobSystemInstanceCollection = lobSystem.GetLobSystemInstances();
            clientContext.Load(lobSystemInstanceCollection);
            clientContext.Load(entity);
            clientContext.ExecuteQuery();

            Microsoft.BusinessData.MetadataModel.LobSystemInstance lobSystemInstance = lobSystemInstanceCollection[0];

            Microsoft.BusinessData.MetadataModel.Collections.FilterCollection externalFiltersOnFieldCollection = entity.GetFilters(readListInstanceName);
            List<string> searchFilters = new List<string>();
            clientContext.Load(externalFiltersOnFieldCollection);
            clientContext.ExecuteQuery();
            foreach (Microsoft.BusinessData.MetadataModel.Filter filter in externalFiltersOnFieldCollection)
            {
                if (filter.FilterField.Equals(ConfigurationManager.AppSettings["filter"]))
                {
                    searchFilters.Add(filter.Name);
                }
            }
            foreach (string filterName in searchFilters)
            {
                externalFiltersOnFieldCollection.SetFilterValue(filterName, 0, ConfigurationManager.AppSettings["filtervalue"]);
            }
            Microsoft.BusinessData.MetadataModel.Collections.EntityInstanceCollection result = entity.FindFiltered(externalFiltersOnFieldCollection, readListInstanceName, lobSystemInstance);
            clientContext.Load(result);
            clientContext.ExecuteQuery();
            return result;

Calling clientContext.ExecuteQuery(); was throwing an error - "An exception of type 'Microsoft.SharePoint.Client.ServerException' occurred in Microsoft.SharePoint.Client.Runtime.dll but was not handled in user code System.ArgumentNullException: Value cannot be null.  Parameter
name: unescapedStr   "

The resolution of this issue was pretty straight forward but not very obvious.

This exception is thrown when a BCS Model Does not contain the ReadItem aka SpecificFinder method.

Now the question arises why does calling the BCS Read List method require the ReadItem method.

If we look at the stack trace in ULS log we see the following

Exception occured in scope Microsoft.SharePoint.BusinessData.MetadataModel.Collections.AbstractEntityInstanceCollection._SerializeToJson.
Exception=System.ArgumentNullException: Value cannot be null.  Parameter
name: unescapedStr   

 at Microsoft.BusinessData.Infrastructure.Util.Escape(Char
valueToEscape, String unescapedStr)    at
Microsoft.SharePoint.BusinessData.BCSObjectFactory.GetEntityInstanceCanonicalId(IEntityInstance
entityInstance)    at
Microsoft.BusinessData.ServerStub.Runtime.AbstractEntityInstanceServerStub.GetObjectIdentity(Object
target)    at
Microsoft.SharePoint.Client.ServerStub.WriteAsJson(JsonWriter writer, Object
obj, ClientObjectQuery objectQuery, ProxyContext
proxyContext)    at
Microsoft.SharePoint.Client.ServerStub.WriteChildItems(JsonWriter writer,
Object obj, ClientObjectQuery objectQuery, ProxyContext
proxyContext)    at
Microsoft.SharePoint.Client.ServerStub.WriteAsJson(JsonWriter writer, Object
obj, ClientObjectQuery objectQuery, ProxyContext
proxyContext)    at
Microsoft.SharePoint.Client.ServerStub.WriteAsJsonWithMonitoredScope(JsonWriter
writer, Object value, ClientObjectQuery objectQuery, ProxyContext proxyCon

The exception is actually thrown at Microsoft.BusinessData.Infrastructure.Util.Escape but the real error happens at Microsoft.SharePoint.BusinessData.BCSObjectFactory.GetEntityInstanceCanonicalId

It seems like the API internally uses the name of the ReadItem method to generate an identifier used internally (i didn't go into further details on where this is used ).

If the ReadItem method does not exist null is passed to the Microsoft.BusinessData.Infrastructure.Util.Escape method which does some kind of encoding of strings and the above exception is thrown.

Though i cannot really visualize a scenario where we don't need the ReadItem method I tried to find any documentation where it is mentioned that ReadItem is required in BCS Model.

I couldn't find any specific documentation but can see that all samples always include the ReadItem method.

Also if you make the External Content Type in SharePoint Designer you should be able to see a warning message if you don't have the ReadItem method.

 

I will conclude that it is safe to say that ReadItem is a required method in the External Content Type.

Hopefully this post will save someone the pain of further troubleshooting when they come across this issue.

Comments (1)

  1. diomos says:

    Thanks! I actually didn't have same issue, however it was related to the one I was trying to solve. In my case, I was getting:

    Microsoft.SharePoint.Client.ServerException: Method Instance with the given name is not found. This generally occurs when the method instance name is incorrect or not available

    But the case was same, we were missing "Read List" operation

Skip to main content