Update list items with listdata.svc
By Anatoly Mironov
In one of my previous posts I showed how to retrieve data from listdata.svc with jQuery $.getJSON method. Getting data is very simple, listdata.svc provides a powerful restful interface with filtering, expanding and other features. Read the best and short introduction to listdata.svc by Suneet Sharma or a more detailed and technical article about filters, functions and operators by Mike Flasko at Microsoft with short examples here. Now back to listdata.svc in the SharePoint environment. Corey Roth provides a good images and sample results. For REST the “http verbs” are very important: GET, POST, PUT, DELETE.. SharePoint RESTful interface defines these verbs like that:
HTTP verb
Data operation
GET
Retrieve
POST
Create
PUT
Update (update all fields and use default values for any undefined fields)
DELETE
Delete
MERGE
Update (update only the fields that are specified and changed from current version)
If you want to dive into http verbs in the listdata.svc, install cURL and follow the awesome tutorial at JustinLee.sg. See this slideshare presentation for a quick introduction: [slideshare id=7699859&doc=developingwithdatatechnologies-110421185725-phpapp01] Allright, a higher level of retrieving and updating of data from listdata.svc is presented by Lee Richardson. Lee uses live binding datacontext, which gives you to save changes: dataContext.saveChanges. Another approach is Client object model.
Retrieve data
I’ll give a try $.ajax. We’ll see if it works. The goal is to update an existing item. Let’s take a usual Task list. I have a site in Norwegian (nb-NO), so we’ll see how well it is suited for i18n. To retrieve all uncompleted tasks for “contoso\administrator”, we can put this into the browser address bar:
http://contoso/\_vti\_bin/ListData.svc/Oppgaver?$filter=StatusValue ne 'Fullført' and TilordnetTil/Konto eq 'contoso\\administrator'
```The invoke is case insensitive. This uses two filters. To invoke this method with ajax, paste it into $.getJSON:
$.getJSON(“http://contoso/_vti_bin/ListData.svc/Oppgaver?$filter=StatusValue ne ‘Fullført’ and TilordnetTil/Konto eq ‘contoso%5cAdministrator’”, {}, null );
#### Create a new item
To create an item, we have to use the POST verb and send a JSON serialized data in a body.
//create var url = “/teamsite/_vti_bin/ListData.svc/MyContacts”; var contact = { FirstName: “Arnie”, Title: “Dell”, WorkCity: “Lund” }; var body = JSON.stringify(contact); $.ajax({ type: “POST”, url: url, contentType: ‘application/json’, processData: false, data: body, success: function () { alert(‘Contact Saved.’); } });
#### Update an item
[As described in the Microsoft resource](http://msdn.microsoft.com/en-us/library/ff798339.aspx), to update an existing item from javascript, the best verb is POST with MERGE settings. Provide this js function:
beforeSendFunction = function (xhr) { xhr.setRequestHeader(“If-Match”, “*”); // Using MERGE so that the entire entity doesn’t need to be sent over the wire. xhr.setRequestHeader(“X-HTTP-Method”, ‘MERGE’); }
$.ajax({ type: “POST”, … beforeSend: beforeSendFunction, });
var mods = {}; mods.Tittel = “hello verden” var body = Sys.Serialization.JavaScriptSerializer.serialize(mods);
Now we can post it:
$.ajax({
type: “POST”,
contentType: “application/json; charset=utf-8”,
processData: false,
beforeSend: beforeSendFunction,
url: “/_vti_bin/ListData.svc/Oppgaver(3)”,
data: body,
dataType: “json”,
success: function() { console.log(“success”); },
error: function() { console.log(“error”); }
});
```And it works! The beforeSendFunction
can be replaced with headers
:
//update
var url = "/teamsite/\_vti\_bin/ListData.svc/MyContacts(3)";
var mods = {
FirstName: "Tolle"
};
var body = JSON.stringify(mods);
//update, another example
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
processData: false,
**headers: {
"If-Match": "\*",
"X-HTTP-Method": "MERGE"
},**
url: url,
data: body,
dataType: "json",
success: function() { console.log("success"); },
error: function() { console.log("error"); }
});
```To update the status is easy too:
var mods = {}; mods.StatusValue = “Fullført” var body = Sys.Serialization.JavaScriptSerializer.serialize(mods); $.ajax({ type: “POST”, contentType: “application/json; charset=utf-8”, processData: false, beforeSend: beforeSendFunction, url: “/_vti_bin/ListData.svc/Oppgaver(3)”, data: body, dataType: “json”, success: function() { console.log(“success”); }, error: function() { console.log(“error”); } });
var mods = {}; mods.Tittel = “david”; mods.TilordnetTilId = 14; var body = Sys.Serialization.JavaScriptSerializer.serialize(mods);
$.ajax({ type: “POST”, contentType: “application/json; charset=utf-8”, processData: false, url: “/_vti_bin/ListData.svc/Oppgaver”, data: body, dataType: “json”, success: function() { console.log(“success”); }, error: function() { console.log(“error”); } });
Unfortunately I didn't find any way to set "assigned to" account name, I had to set Account ID (mods.**TilordnetTilId** = 14). To delete an item, just use $.ajax and DELETE verb:
$.ajax({ type: “DELETE”, contentType: “application/json; charset=utf-8”, processData: false, url: “/_vti_bin/ListData.svc/Oppgaver(3)”, data: {}, dataType: “json”, success: function() { console.log(“success”); }, error: function() { console.log(“error”); } });
##### Localization
What about i18n and localization? It is actually not so generic. One solution could be localizable javascript enums. The fact that the properties are translated can lead to problems. The first time I load the page after deploy, restart or app pool recycling, I get 400 error (bad request). The explanation can be found in the Response:
{ “error”: { “code”: “”, “message”: { “lang”: “sv-SE”, “value”: “No property ‘TilordnetTilId’ exists in type ‘Microsoft.SharePoint.Linq.DataServiceEntity’ at position 30.” } } }
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { RegisterLocalizationScript(); } }
private void RegisterLocalizationScript() { var completed = SPUtility .GetLocalizedString(“core”, “Tasks_Completed”, (uint)CultureInfo.CurrentCulture.LCID); var ongoing = SPUtility .GetLocalizedString(“core”, “Tasks_InProgress”, (uint)CultureInfo.CurrentCulture.LCID); var script = string.Format(“completedString = ‘{0}’;ongoingString = ‘{1}’”, completed, ongoing); Page.ClientScript.RegisterStartupScript(GetType(), “todo-localized-values”, script, true); }
// this is used to retrieve and update todos with listdata.svc web service Task = { completed: “Fullført”, //$Resoures:core.resx, Tasks_Completed inProgress: “Pågår” //$Resoures:core.resx, Tasks_InProgress }
##### Datetime
To retrieve and order it after creation date add $orderby:
http://contoso/_vti_bin/ListData.svc/Oppgaver?$filter=StatusValue ne ‘Fullført’ and TilordnetTil/Konto eq ‘contoso\administrator’$orderby=Opprettet desc
http://contoso/_vti_bin/ListData.svc/Oppgaver?$filter=Endret+ge+datetime'2011-11-23T00:00:00’
var date = new Date(); date.setDate(date.getDate()-7); var lastWeekISO = date.toISOString(); $.getJSON(“http://contoso/_vti_bin/ListData.svc/Oppgaver?$filter=Endret ge datetime’” + lastWeekISO + “’”, {}, null );
var today = new Date(); task.Forfallsdato = today.toISOString();
##### Misc
Only after I wrote this I found [a very nice intro to REST by Jan Tielen](http://weblogs.asp.net/jan/archive/2010/10/05/getting-started-with-jquery-templates-and-sharepoint-2010.aspx "See Jan Tielen's blog entry about listdata.svc, rendering, even with richt html"). The alternative is [to use SPServices or maybe SPRest or SPELL by Christophe by Path To Sharepoint](http://blog.pathtosharepoint.com/2011/05/02/two-new-projects-sprest-and-spell/ "Read about some REST abstraction initiatives for Sharepoint on codeplex"). The alternative way to [retrieve list items](http://msdn.microsoft.com/en-us/library/hh185007.aspx "See the documentation and examples how to retrieve list items using javacript client object model") and [update them](http://msdn.microsoft.com/en-us/library/hh185011.aspx "See the documentation and examples how to upate list items using javacript client object model") is to use [Client Object Model (CSOM)](http://msdn.microsoft.com/en-us/library/ee535231.aspx "See the Client object model resources on msdn"). One of the advantages of Client Object Model is that you don't need to care about the localization of column names and status values. You can rely on static names like you do in the Server Object Model when you use CAML. This image shows differences for retrieving 10 list items using lisdata.svc vs csom: [![](https://sharepointkunskap.files.wordpress.com/2011/12/listdata-svc-vs-csom-for-10-items.png "listdata.svc-vs-csom-for-10-items")](https://sharepointkunskap.files.wordpress.com/2011/12/listdata-svc-vs-csom-for-10-items.png)
## Comments from Wordpress.com
####
[Using ListData service in SharePoint 2010 « Simple Stuffs](http://akurniaga.wordpress.com/2012/09/27/using-listdata-service-in-sharepoint-2010/ "") - <time datetime="2012-09-27 08:29:10">Sep 4, 2012</time>
\[...\] can also use ListData service to create a new list item or update an existing item. Credits go to Anatoly Mironov for explaining on how to perform save and update operations. Following our example above, \[...\]
<hr />
####
[Filter / Sort / and return JSON with listdata.svc and Sharepoint 2010 « Casey's Tech Blog](http://csleetechblog.wordpress.com/2012/12/27/filter-sort-and-return-json-with-listdata-svc-and-sharepoint-2010/ "") - <time datetime="2012-12-27 20:21:36">Dec 4, 2012</time>
\[...\] https://sharepointkunskap.wordpress.com/2011/12/15/update-list-items-with-listdata-svc/ \[...\]
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-06-07 16:51:27">Jun 5, 2013</time>
Hi JP, the "success" result can be misleading. Maybe, it is 200 - OK result in a http request. But there is some error. Please see what the response says. In Chrome open the Netwokr tab, in IE there is a tool for that as well.
<hr />
####
[JP]( "joshipaul@gmail.com") - <time datetime="2013-06-07 18:13:18">Jun 5, 2013</time>
I found the issue and fixed it. When you publish the InfoPath 2010 form to a Doc lib in the Publishing wizard->Field column, there is a check box 'Allow users to edit data in this field by using a datasheet or properties page'. This has to be checked. That did the trick.
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-06-07 18:38:52">Jun 5, 2013</time>
Great! Cool that you found the reason why it was so. Thank you for sharing the solution.
<hr />
####
[Alexander Zaytsev]( "zaitsman@hotmail.com") - <time datetime="2013-05-21 01:00:14">May 2, 2013</time>
Hi Anatoliy, Is it possible to upload files using the MERGE verb or otherwise? Thank you.
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-05-23 11:56:30">May 4, 2013</time>
Hi Alexander, to be honest, I never have tried to upload a file with listdata.svc. In the new REST API you can upload files. How far did you come when you tried to upload files with MERGE? If you have some code you are testing, let me know, I can run it on my machine and try to help you to figure out if it is possible or not.
<hr />
####
[JP]( "joshipaul@gmail.com") - <time datetime="2013-06-07 02:01:43">Jun 5, 2013</time>
Hi Anatoly, I am trying to update a DocLib(stored as xml) using the REST listdata.svc. I got a update success alert message but when I open the xml doc using InfoPath forms I do not see the updated value. Any idea why?
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-05-08 20:40:07">May 3, 2013</time>
Hi Jacob. Sorry for a late answer. What do you mean by deeper level? Is it a subsite? Then it is no problem. Just adjust the url as you did in the example http://portal/site/\_vti\_bin/listdata.svc/WhateverListItMayBe If you want to add list items in a folder inside a list, then I am not that sure. Theoretically it should work, but I haven't tried it yet. Hope it helps.
<hr />
####
[Jacob Flatter (@j_flatter)](http://twitter.com/j_flatter "j_flatter@twitter.example.com") - <time datetime="2013-04-11 20:01:57">Apr 4, 2013</time>
Is it possible to Add list items at levels deeper than top level? All of the examples I have seen are like > http://portal/\_vti\_bin/listdata.svc/Announcements and I am trying to add an item to a list more like > http://portal/site/\_vti\_bin/listdata.svc/HQAnnouncements . Am I barking up the wrong tree? Thanks, Jacob
<hr />