On the previous week I had a speech on the Finland Sharepoint User Group in Helsinki. It was nice to met new people and participate in Finland community’s professional life. Hope that my presentation about data retrieving methods in Sharepoint (LINQ 2 Sharepoint, CAML, Camlex.Net, ContentIterator, etc.) which was mostly developers-oriented was not so boring for non-developers who presented on the meeting :) Also I hope that it was only beginning and we will have more meetings and interesting discussions in the future.
Wednesday, June 15, 2011
Sunday, June 12, 2011
In one of my previous posts I described how to create custom error handler for the RESTful endpoints in WCF service. It uses simple idea: store exception message into Status Description field, so e.g. if with standard handler you got something like this:
HTTP/1.1 500 Internal Server Error
Then in with custom error handler you will get the following:
HTTP/1.1 500 InternalServerError: Customer Id can’t be empty
So when such exception will be handled on the client side you will have its actual reason. It was done using the following code in custom error handler:
And it works. But recently I found one problem with this approach (quite predictable I would say): with using HTTPS you may get the following exceptions from the server:
The server committed a protocol violation
Because of some reason for simple HTTP protocol it was not thrown (however for HTTPS it also was not regular). Anyway this is a problem which we should address and found more correct way to handle exceptions on the client side.
First of all I turned off my custom handler and ensure that problem is not reproducible without it. Of course I got only generic “Internal Server Error” again. After it I checked from where this exception is thrown on the client (remember that we are talking about RESTful endpoints – which use WebHttpBehavior. JSON and SOAP endpoints are out of scope in this post. I will describe them in the future posts). It is thrown in the WebFaultClientMessageInspector internal class which implements IClientMessageInspector interface:
(Another method of the interface BeforeSendRequest(…) just returns null).
Now it became clear why we always got generic “Internal Server Error” exception for the RESTful endpoints. Also it became clear why we can’t use FaultExceptions<FaultContract> for the RESTful service – it is ignored on client side and CommunicationException is thrown instead.
How to solve this problem? The answer is obvious: create custom implementation IClientMessageInspector and use it on client. Remember that it is called on the client side (on server side there is equivalent IDispatchMessageInspector). But how to send error message to the client? I used custom HTTP header with base64 encoded string. Algorithm is the following:
- On the server side register and use custom error handler as shown in the previous article.
- Instead of modifying of StatusDescription field we store error message in custom HTTP header (preliminary converted to base64 string)
- On the client side we use custom message inspector – check the custom HTTP header and if it is not empty, decode it and rethrow exception with initial error message
- As result we will have the exception with the same error message as initially thrown from the server
Now lets check the code. First of all we need to modify our custom error handler on the server:
Now we need to catch it on the client. Create custom client message inspector:
The only remaining way is to register it on the client side. In order to do it we need to create custom inheritor of the WebHttpBehavior class and register our own message dispatcher instead of standard one:
Now in order to register it via config file of our client application we need to create custom extension element:
After these manipulations we can register and use our custom message dispatcher in client’s config file:
Now on client we will get server’s error message without problems with protocol violation.
Tuesday, June 7, 2011
In this post I would like to describe useful class which can be helpful in your every day Sharepoint development: ContentIterator. This class is defined in Microsoft.Office.Server.dll assembly and helps address common tasks like iteration through list items (SPListItem), files (SPFile), sites (SPWeb), etc. The cool thing is that it is implemented via SPQuery and so it has very good performance on the big lists. Also as documentation says:
SharePoint Server provides a new API, ContentIterator, to help with accessing more than 5,000 items in a large list without hitting a list throttling limit and receiving an SPQueryThrottleException
E.g. suppose that we have reference on SPFolder and want to iterate through all items in this folder. We can use ContentIterator.ProcessFilesInFolder method:
So we passed doclib and folder where we want to perform iteration, Third parameter specifies should iteration be recursive or not. Fourth parameter is the function which receives actual SPFile instance which was iterated. And last parameter is the error handler.
Lets see how it is implemented. In the underlying calls it uses another method ContentIterator.ProcessListItems. At first it constructs SPQuery object:
String strQuery used here is calculated on the above call stacks:
And the most interesting implementation of ProcessListItems method overload:
It sets row limit (to 200 or 2000 depending on the is ViewFields property specified or not). Then it sets SPQuery.QueryThrottleMode property to Strict. According to documentation it means:
Throttling for both the number of items and for number of Lookup, Person/Group, and Workflow Status fields will apply to the query regardless of user permissions.
Also it uses SPQuery.ListItemCollectionPosition property for retrieving items by batches using RowLimit as number of items per batch.
As you can see ContentIterator makes a lot of hidden infrastructure work for you. So it can economy your time and allow to concentrate on the business tasks.