A better SharePoint Connector – part 5: The beauty of complexity

The SharePoint Connector is coming along pretty well. The basic functionality has been implemented. At the moment I can Add a new file, download it and delete it afterwards. What remains to be done is storing the accompanying meta data with the document. This is actually the hardest part in the development of the connector.

When looking at SharePoint Lists, a document library is a special breed. Where a regular list is based on list items (which actually can have attachments), is a document library based on files which have a list item attached. Actually it is the other way around. This means that adding a new item to a document library is a two step process, in contrast with adding a new item to a list (which is a single step process).

DocumentLibraryVersusList

  1. The document is uploaded to SharePoint. A SPFile object is created and a SPListItem is attached.
  2. The meta data is inserted in the new SPListItem object.

Fortunately the SharePoint REST API is helping us in this two step process. Uploading a document results in a JSON blob, containing all the information we need to get a reference to the SPListItem attached to the uploaded document. See example below:

{"d":{"__metadata":{"id":"Web/GetFileByServerRelativeUrl('/shared documents/test.zip')",
"uri":"http://dev-bvdsande:8080/_api/Web/GetFileByServerRelativeUrl('/shared%20documents/test.zip')",
"type":"SP.File"},
"Author":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/GetFileByServerRelativeUrl('/shared%20documents/test.zip')/Author"}},
"CheckedOutByUser":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/GetFileByServerRelativeUrl('/shared%20documents/test.zip')/CheckedOutByUser"}},

"ListItemAllFields":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/GetFileByServerRelativeUrl('/shared%20documents/test.zip')/ListItemAllFields"}},

"LockedByUser":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/GetFileByServerRelativeUrl('/shared%20documents/test.zip')/LockedByUser"}},
"ModifiedBy":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/GetFileByServerRelativeUrl('/shared%20documents/test.zip')/ModifiedBy"}},
"Versions":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/GetFileByServerRelativeUrl('/shared%20documents/test.zip')/Versions"}},
"CheckInComment":"",
"CheckOutType":2,
"ContentTag":"{3F8B526C-4C68-4B24-BB10-8B680EE6F660},1,1",
"CustomizedPageStatus":0,"ETag":"\"{3F8B526C-4C68-4B24-BB10-8B680EE6F660},1\"",
"Exists":true,
"Length":"35190",
"Level":1,
"MajorVersion":1,
"MinorVersion":0,
"Name":"test.zip",
"ServerRelativeUrl":"/shared documents/test.zip",
"TimeCreated":"2015-01-13T20:46:14Z",
"TimeLastModified":"2015-01-13T20:46:14Z",
"Title":null,
"UIVersion":512,
"UIVersionLabel":"1.0"}}

Line 7:  "ListItemAllFields":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/GetFileByServerRelativeUrl('/shared%20documents/test.zip')/ListItemAllFields"}} returns us the REST call we need to perform to get a reference to the attached SPListItem object.

When we execute the REST call in line 7, we get the following results:

{"d":{"__metadata":{"id":"Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)",

"uri":"http://dev-bvdsande:8080/_api/Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)",

"etag":"\"1\"",
"type":"SP.Data.Shared_x0020_DocumentsItem"},
"FirstUniqueAncestorSecurableObject":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)/FirstUniqueAncestorSecurableObject"}},
"RoleAssignments":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)/RoleAssignments"}},
"AttachmentFiles":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)/AttachmentFiles"}},
"ContentType":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)/ContentType"}},
"FieldValuesAsHtml":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)/FieldValuesAsHtml"}},
"FieldValuesAsText":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)/FieldValuesAsText"}},
"FieldValuesForEdit":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)/FieldValuesForEdit"}},
"File":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)/File"}},
"Folder":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)/Folder"}},
"ParentList":{"__deferred":{"uri":"http://dev-bvdsande:8080/_api/Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)/ParentList"}},
"FileSystemObjectType":0,
"Id":8,
"ContentTypeId":"0x010100851EE10E271C4A4EA705D85000D5FC69",
"Title":null,
"Description0":null,
"SomeNumber":null,
"MoreText":null,
"MyChoice":"Keuze 1",
"ID":8,
"Created":"2015-01-13T22:22:43",
"AuthorId":1073741823,
"Modified":"2015-01-13T22:22:43",
"EditorId":1073741823,
"OData__CopySource":null,
"CheckoutUserId":null,
"OData__UIVersionString":"1.0",
"GUID":"191aafb5-3f8a-46e8-af76-f200f288480d"}}

Line 3: "uri":"http://dev-bvdsande:8080/_api/Web/Lists(guid'0ceeae1d-e6cc-4699-bc6c-0e1f1e7e0974')/Items(8)" gives us the reference to the ListItem in the document library. Using the Guid of the list and the ID of the item, we are now capable of setting the meta data.

I my previous article I made a wrong assumption. I mentioned that the “ContentTag” was returning the document id, which is not true!

Anyway I’m close to the resolution of the problem. In my next article, I’ll wrap up the SharePoint side of things and return to CRM.

Leave a Reply

Your email address will not be published. Required fields are marked *