Showing posts with label Visual Studio. Show all posts
Showing posts with label Visual Studio. Show all posts

Tuesday, July 26, 2016

Create document set in SharePoint Online with CSOM

It's very easy to create a document set in SharePoint Online (Office365) with csom. There is not really an API available at this moment, but by converting a folder we can achieve our goal.

If your DocumentSet content type contains other content types, you could end up with a yellow banner saying:
Content types that are available to this Document Set have been added or removed.  Update the Document Set.
If you see this banner, the content types under the new button aren't correct either. You can fix this by setting docset_LastRefresh and vti_contenttypeorder folder properties.

cheers!

Wednesday, March 2, 2016

Change site title for all languages with CSOM

If you want to update the site title of a SharePoint site you probably will use the title property of your web object. ok, but this will only update the site title in the language of the user that runs the code.

e.g. my user account has set English as default display language



If you update web.title property trough the UI or via custom code, change your default display language to another language and load the site again, the web.title property won't be changed in this language.

You can use this piece of code to change the title property for all available languages of a site.


Wednesday, December 3, 2014

Upload file in SharePoint online document library (folder) with REST and active authentication.

In this post I'll explain you what I did to upload a local file into a SharePoint Online Office 365 document library. The second step in this example is providing the new document with a proper value for the title meta data field.
This example is a console application written in C#, not using the Microsoft.SharePoint.Client.dll but only making calls to REST endpoints.
A CRM developer asked me to write this piece of code so he could implement this logic into a custom CRM module, that module had to copy a file from CRM online to SharePoint online.

When the application is launched the console will ask you for some parameters:
  • path of the file to upload
  • title for the new document 
  • document library name
  • folder name (in this example, I expect a folder)
  • site collection URL (in this example, sub sites are not taken into account)
  • O365 user name
  • password
As you see, the application will ask for a user name and password. These credentials are used to authenticate the application with SharePoint. I've used the authentication mechanism build by Wictor Wilén. If you're interested in this authentication mechanism you definitely should read his post.

This console app is just an example on how we can upload a document. The SharePoint document library and the folder must exist, the code won't create them for you. If they don't exist, the code will throw a 404 exception.

If everything goes well, you should see something like this:



Where the magic happens

The download link is available at the end of this article. Download and adapt for your needs.

As explained earlier the application exists of 3 blocks
  1. authentication -> get security token by calling STS of Office 365. This security token is sent to SharePoint, if SharePoint accepts it will return 2 cookies. Those cookies we have to include in each (REST) request we do to SharePoint.
  2. Reading the local file as a byte array and uploading the file in the correct folder.
  3. When the upload is succesfull, we give the Title metadata field a proper value.

Reading and uploading the file with REST (c#)

Following code snippets are only there for explaination reasons, download the full example to get a working application.

When authentication is succesfull and we have the 2 required cookies in our container, I have to obtain the formdigest, this digest is mandatory if your REST call is writing data to SharePoint. We will inlcude this formdigest as property X-RequestDigest in the header of the request. The binaryStringRequestBody property is the second one we add in the header. This property is mandatory because we will upload a document as a byte array.
When preparations are done we can actually do the webrequest by calling HttpHelper.SendODataJsonRequest. After including the cookies, this function will call SendHttpRequest() where the actual request is done. Properties of the request:

  • request.Method = "POST"
  • request.Accept = "application/json;odata=verbose"
  • request.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)"; //must be there, otherwise http 403 error
  • request.AllowAutoRedirect = false; // This is key, otherwise it will redirect to failed login SP page
  • request.Headers
    • binaryStringRequestBody: true
    • X-RequestDigest: [value of formDigist]
  • request.ContentType = "application/json;odata=verbose"
  • request.ContentLength = requestContent.Length;
  • request.GetRequestStream() -> read byte array of file.


Changing Title metadata field of the fresh document.

Second step is to give the new document a proper title. In fact the process is very similar to the upload of the document. Here a list of the differences:

  • body: instead of processing the byte array of the document, now the body of the request will contain a string in which we define the changes to the metadata.
  • headers: since we are doing again a POST request, the X-RequestDigest is again required for security reasons. 2 other properties are required as well:
    • X-HTTP-Method = MERGE
    • IF-MATCH = *
The MERGE method updates only the properties of the entity that you specify.

Here you can download the Visual Studio Project.

**UPDATE: Since System.Web.Extensions is not available in a CRM sandboxed solution, json deserialization is done with System.Runtime.Serialization.Json. Thanks to Kris for helping me out.


Friday, July 11, 2014

Register remote event receiver (RER) with CSOM

I'm currently working on a provider hosted SharePoint 2013 app. The aim is to build a self provisioning app by making use of the client side object model  (csom).

In an old fashion way, provisioning of site columns, content types, lists... was done with declarative coding. Unfortunately, declarative host web provisioning isn't possible. Luckily for us developers, the OfficeAMS contributors are working hard on building nice extension methods to speed up SharePoint development. 

in the following example I'm provisioning the host web during the AppInstalled event.
  • creating a new list
  • binding the remote event receiver to the newly created list
The remote event receiver is a .svc service hosted on the remote web of the provider hosted app. In my example I'm using Azure.

In fact, binding the RER isn't rocket science, but since the ReceiverUrl property is set to the absolute address of the .svc we won't be able to debug this thing. If we want to debug a remote event receiver hosted on Azure we have to make use of an azure service bus.

This is why I'm using the #if DEBUG directives of visual studio. If in debug mode, I'm overwriting the absolute .svc url in the following format:
https://server.servicebus.windows.net/computer/account/obj/guid/EventReceiver.svc 

This raises the question, what are the computer, account and guid parameters in this URL? I figured out these values by opening the .debugapp package that is generated by visual studio during debugging.

While debugging you can find this package in the debug folder of your project.
Extract this .debugapp package and open the AppManifest.xml file in a text editor.
The InstalledEventEndpoint contains all the values your are looking for.