Welcome to my blog, stay tunned :
Home | Blogs | Stephane Eyskens's blog

What I presented at the BIWUG

Warning: I've just (on Sun. may 16) re-amended the code to be compatible with the RTM.
Today, after a trafic jam session (thanks Vilvoorde...) because of which I got late, I presented a session on how WCF is integrated into SharePoint 2010 beta2 (I've not tested yet on the RTM bits) and more particularly how you can benefit from the RESTFUL services and more particularly from ListData.svc.

After having explained the basics of REST url constructs with SharePoint, I made 3 demos of two little apps which are available for download as well as the presentation and 1 demo on how to manipulate REST urls with ListData.svc.

The first demo is related to a post I published in feburary and which is available here : http://www.silver-it.com/node/56

The secund demo was Using jQuery to consume ListData.svc and to perform CRUD operations. To serve that topic, I've built a kind of datagrid tool entirely based on jQuery (a simple .htm page using some javascript) and ListData.svc. Here are some screenshots of the very sexy little app :)).

When clicking on the info icon, you get the full JSON object data returned by ListData.svc and when clicking on the update icon, you get the possiblity to modify the item title:

You can also delete the items and insert new items. All of this is done with REST calls only. You can download the full code but basically, what you need to remember is the following:

- When retrieving items, you basically need to perform a GET HTTP request like the following:

Here, I specify that I want to retrieve all the Cities from the corresponding list. I add each returned item in a HTML list control. I also specify via getJSON that I want to manipulate JSON objects.

Basically, the way you get data will always look like this one. The only thing that will vary is the URL. Again, to have more info on it, read my older post .

- When deleting items, you might use something like the following:

It's even easier than getting items because you don't need to specify a content type since you don't send nor retrieve any data.

The other two operations are a little bit more complex, at least, according to my investigations...

- When inserting items, you can do this way:

The highlighted part consists in creating a new customer item. Then, we make a HTTP POST call, pass the "stringified" JSON object we've just created and then treat the error. Surprisingly, even though a code 201 is returned by ListData.svc, the jQuery call branches to the error handler (that's why I didn't use a success handler....and that's also why there is a test on the error code returned...

The secund part of the insert operation is to retrieve the ID of the newly created item. If you analyze such a query with fiddler, you'll notice that the response for such a query in case of success looks like this:

You see that 201 is indeed the returned status, the Etag that's required when updating data is also returned and the ID of the created record (in this case 120) is also returned. A separate node not shown in this picture also contains the ID.

So, when you insert a new listitem, the service gives it back to you...However, it seems that there is no way to get it back in JSON format. That's why, in my code, I performed an extra query to get the JSON object via a custom function called GetInsertedCustomer...In real world, you'd better avoid that extra query though...

- When updating data, it's even more complicated, that was in fact the most complicated operation:

Highlighted, you can see that the ETag value of the item is transmitted to ListData.svc. In Beta2, you're forced to do it otherwise you'll get an error notifying you that you didn't provide the system with a valid ETag. The operation is a MERGE operation, the data is the stringified JSON object and last but not least, you need to make sure you exclude the date columns "Created" and "Modified" from the JSON object before sending it back to SharePoint.

If you don't, you'll get a 400 (Bad Request) error from ListData.svc. In Beta2, I didn't find an alternative.

Again, when analyzing the result with Fiddler, you'll notice that the status code is 204 and that the new etag is returned:

In my code, as for the insert operation, I perform an extra request to get the updated object. In the real world, you should try to read the value of the new ETag returned by the service which will be required if you plan to make other updates on the same object. You need to transmit the ETag for each update operation since it changes from one update to another...

That's where the CRUD demo stopped...Note that I tried to use a javascript proxy but again, in beta2, I've never been able to generate such a proxy...

The last demo was Create your own WCF REST service, integrate it into SharePoint & consume it via jQuery.

The little app is quite basic:

You get the list of document IDs of a given document library (the one you specify in the URL), and you can get the metadata of those documents when picking an item from the list. The contract exposes two operations:

For the rest, I suggest you to download the code since most of the implementation is similar to a classic WCF implementation. The only SharePoint related steps are:

- You need to deploy your SVC file somewhere under ISAPI (custom folder for instance)
- In your SVC file, you can (not forced) use one of the built-in SharePoint factories that will help you to deal with your service (endpoints etc...). Three factories are available:

- MultipleBaseAddressWebServiceHostFactory for SOAP services
- MultipleBaseAddressDataServiceHostFactory for DATA services
- MultipleBaseAddressBasicHttpBindingServiceHostFactory for REST services

Those three factories are listed here http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spwebservice_members(office.14).aspx.

- If you want to deal with objects such as the SPContext, you need to set the class attribute AspNetCompatibilityRequirements (as for 2007) of your WCF service to mandatory.

That's basically it!

The PowerPoint presentation I used is available here. The Visual Studio solution is available here.

The solution is based on a site that has the following structure:

There is a relationship between Customers and Cities based on the lookup column City and there is another relationship between Cities and Countries based on the lookup column Country.

Here are the list templates...but you might need to rebuild them from scratch according to your SharePoint bits :).

Enjoy!

Comments

Set If-Match with C#?

Greetings!

I know it has been awhile you wrote this post, but I am struggling with the eTag - 400 error in my implementation of the ListData.svc. Do you know how to set that "if-Match" request header using C#?

Thanks,
-Nick

implementation from c#

Hi,

You don't need to find yourself. If you're working with c#, you can just add a service reference to your project Add Service Reference => Site Url/_vti_bin/ListData.svc.

Then, you can use the proxy that was generated by Visual Studio. Say, this piece of code for instance:

lst.tsContext ctx = new lst.tsContext(
  new Uri("http://intranet.contoso.com/_vti_bin/Listdata.svc"));
ctx.Credentials = System.Net.CredentialCache.DefaultCredentials;
var TargetItem = ctx.Clist.Where(i => i.Id == 1).SingleOrDefault();
TargetItem.Title = "update 1";
ctx.UpdateObject(TargetItem);
ctx.SaveChanges();
TargetItem.Title = "update 2";
ctx.UpdateObject(TargetItem);
ctx.SaveChanges();

This will take item having id 1 of a list called "clist". Then, it performs two updates in a row on that item. Behind the scenes, with Fiddler, you see that it's indeed always sending the Etag to the request. When the first update is done, SharePoint sends back the new value of the Etag. When the 2nd update takes place, the API sends that new value to SP.

But you don't really need to care of that if you're using the service reference.

Best Regards

Oh, sweet, that looks like it

Oh, sweet, that looks like it will work swell, will advise on results.
Thanks,
-Nick