Wednesday, July 11, 2012

SharePoint TermSet and Maximum number of items that can be serialized or deserialized in an object graph is '65536'

We have a business requirement that allows the end users to read certain news articles about the company and like them and based on that it increases the like count and also tags the page with a default SharePoint "I like it" tag. This allows the page to come in the activity feed of the end users allowing his / her colleagues to see the news articles that was liked by him / her.

Everything worked fine until one fine day the custom code started breaking and the error that was getting logged in the ULS logs was

Maximum number of items that can be serialized or deserialized in an object graph is '65536' 


We found that the problem is with the default WCF service limits, as the error indicates it can only serialize 65536 objects. Ok, I understand that but why does the code fail and why is it that if I use SharePoint's native functionality "Like It" works just fine? The answer lied in the custom code that was written to trigger of "I Like it".

The line of code that was the culprit of this error was
Term term = taxSession.DefaultKeywordsTermStore.KeywordsTermSet.Terms["I like it"];

Now you will think ok, that looks perfectly fine but why did it raise the error? The reason is in how SharePoint works, as you can see above the code is actually retrieving the term by indexing on the KeywordTermSet collection. The problem with this approach is that server side code will first bring in the entire collection and then index it and retrieve the actual term. This will work fine if your Managed Metadata Store was present in the same SharePoint farm, but if you have a seperate Shared Service Farm which is hosting your Managed Metadata Store and your code lies in a seperate farm then you will definitely see the issue mentioned above.

To overcome the issue the code was changed to

TermCollection termCollection = taxSession.DefaultKeywordsTermStore.KeywordsTermSet.GetTerms("I like it", true);
Term term = termCollection[0];


This uses the built in function call to only retrieve the term and not the entire collection.

Feel free to comment or raise any questions that you may have and I will more than happy to answer them.

Thanks

No comments:

Post a Comment