Pablo Romeo
Pablo Romeo

Reputation: 11396

Getting ID of item after posting to a document library

I'm currently consuming information from Sharepoint 2010 using WCF Data Services from C# (an asp.net mvc4 application).

With regular Sharepoint lists items, when saving the changes to the context, the id of the new item is automatically populated on the original object. Meaning:

SomeContext context = /* creation of the context*/;
var someEntity = new SomeEntity {...};
context.AddToSomeEntityItems(someEntity);
context.SaveChanges();
var newId = someEntity.Id;      //this will have the new id

However, if what you are creating is an item for a document library, the id doesn't seem to be updated on the saved entity. For example:

SomeContext context = /* creation of the context*/;
var someOtherEntity = new SomeOtherEntity {...};
Stream data = /* some stream*/;
context.AddToSomeOtherEntityItems(someOtherEntity);
context.SetSaveStream(someOtherEntity, data, true, "SomeMIMEType", "SomeSlugPath");
context.SaveChanges();
var newId = someOtherEntity.Id;         //this will instead always have 0

I initially thought this was a bug in the first version of WCF Data Services so I updated to the latest, 5.4.0. But the behavior seems to be the same.

I would prefer to have to avoid strange lookups that ultimately could fail during heavy load, such as using .OrderByDescending(x => x.Id).First() to get the recently created item.

When looking at the actual network traffic using Fiddler, I can see that the initial upload of the binary data actually does return the information for the item along with its ID. And if I configure other relationships to that item using SetLink prior to saving changes they are linked correctly, so the context does handle the value accordingly.

Is there any way to get WCF Data Services to update the ID on the entity when the item is for a document library?

Upvotes: 3

Views: 900

Answers (2)

Andy C.
Andy C.

Reputation: 696

What I am doing is parsing out the id from the response headers:

var responses = context.SaveChanges();
var created = responses.FirstOrDefault(r => r.StatusCode == (int)HttpStatusCode.Created);

if (response != null)
{
    var location = response.Headers.First(h => h.Key == "Location").Value;
    //location will be http://sharepoint.url/site/_vti_bin/ListData.svc/{listname}(id)
    //you can parse out the id from the end of that string
}

It's not exactly elegant, but it works.

Upvotes: 2

Tim Burkhart
Tim Burkhart

Reputation: 658

Typically, I set the Id manually before inserting it with

someOtherEntity.Id = Guid.NewGuid();

That way you can TDD it more easily as well. I think it is best to leave the responsibilities to your code than to rely upon an external storage system to tell you what the Id is.

Upvotes: 2

Related Questions