Update a LookupField value for a SharePoint ListItem using Client Object Model C#

A lookup data in a SharePoint can be treated as a choice options that has been maintained in a different List. Hence if one of your field in your List is a lookup then, its value should be the ID[integer] the actual Lookup-Item (i.e., the list item id of the List as a LookUp).

For ex, in a blog site, List, Category has been used as lookup field for the List Post. By default, in SP2013, you’ll get three items for Categories. Say, their Ids are 1,2, & 3.

  • Events[1]
  • Ideas[2]
  • Opinions[3]
Now if you want to change the Category field of a Post, then, you have to pass the ID of the item and not the text value.

ClientContext ctx = new ClientContext(targetURL);
ctx.Credentials = new SharePointOnlineCredentials(userName, passWord);

this.ctx.Load(this.ctx.Web);
SP.ListCollection listCol = web.Lists;
ctx.Load(listCol);

SP.List list = listCollection.GetByTitle("ListTitle");

SP.CamlQuery camlQuery = new SP.CamlQuery();
camlQuery.ViewXml = "";
SP.ListItemCollection listItemCollection = list.GetItems(camlQuery);
this.ctx.Load(listItemCollection);
this.ctx.ExecuteQuery();

SP.ListItem listItem = listItemCollection.FirstOrDefault(t => t.DisplayName == "NameOfTheListItem");
this.ctx.Load(listItem.FieldValuesAsText); 
this.ctx.ExecuteQuery();

//[Say, for one of the Id mentioned above.]
listItem.FieldValuesAsText["PostCategory"] = 2; 

listItem.Update(); 
this.ctx.ExecuteQuery(); 

To get the id of the listItem Ideas, you’ll have to re-connect to the SharePoint server and get the ID for the text Ideas from the List Category.

NOTE: Here, I have faced a strange issue. If I update any value of the Post Item before updating the lookupField value then the previous made changes were getting overwritten. So I have to ensure that the lookupField value should always get updated first before any other field.

Check-In/Check-Out and Publish/UnPublish files in SharePoint 2013 using the Client Object Model C#


string siteUrl = "http://servername:12345/";
SP.ClientContext ctx = new SP.ClientContext(siteUrl);
ctx.Credentials = new SharePointOnlineCredentials(userName, passWord);
this.ctx.Load(this.ctx.Web);
SP.Web web = this.ctx.Web;
SP.File file = web.getFileByServerRelativeUrl("serverrelativeUrlOfTheFile");

//CheckIn the file
file.CheckIn(String.Concat("File CheckingIn at ", DateTime.Now.ToLongDateString()), SP.CheckinType.MajorCheckIn);

//CheckOut the File
file.CheckOut();

//Publish the file
file.Publish(String.Concat("File Publishing at ", DateTime.Now.ToLongDateString()));

//UnPublish the file
file.UnPublish(String.Concat("File UnPublishing at ", DateTime.Now.ToLongDateString()));

Remember, before making any changes to the state of the file it is always advisable to first check its current state/level. You can check the current state of the file i.e., if the file is currently CheckedOut, Drafted (CheckedIn), OR, Published. You can easily do that by checking the FileLevel value of the file you’re querying. FileLevel is an enum which specifies the publishing level for a file. MoreInfo

***

Programmatically create SiteColumn for a Web in SharePoint using Client Object Model

string siteUrl = "http://servername/";
SP.ClientContext ctx = new SP.ClientContext(siteUrl);
this.ctx.Load(this.ctx.Web);
SP.Web web = this.ctx.Web;

web.Fields.AddFieldAsXml(schemaXML, false, SP.AddFieldOptions.AddFieldToDefaultView);

web.Update();
SP.FieldCollection fieldCollection = web.AvailableFields;
ctx.Load(fieldCollection);
ctx.ExecuteQuery();

SharePoint Client Object Model Error: This functionality is unavailable for field collections not associated with a list.

I got this error while trying to create a SharePoint ContentType using the Client Object Model. The problem occurred when I tried to add an existing field to the new Content Type using the contentType.Fields.Add method.

However, we can only add existing Fields only to a List in this manner. For a ContentType, we have to use the contentType.FieldLinks.Add method. The below commented line was throwing the error. I then replaced the Field with FieldLinks and then, my custom ContentType (Piyush_ContentType)was created with all the SiteColumns of the Parent Content Type (Task) plus one custom SiteColumn, Birthday (Date and Time).

Remember, to mention the contentType.Update(true/false) at the end to map your changes to the server.

Necessary namespace
using Microsoft.SharePoint.Client;
using SP = Microsoft.SharePoint.Client;
string siteUrl = "http://servername:12345/";
SP.ClientContext ctx = new SP.ClientContext(siteUrl);
this.ctx.Load(this.ctx.Web);
SP.Web web = this.ctx.Web;
SP.FieldCollection fieldCollection = web.AvailableFields;
SP.ContentTypeCollection conCollectionList = web.ContentTypes;
ctx.Load(fieldCollection);
ctx.Load(conCollectionList);
ctx.Load(conCollectionList, l => l.Include(t => t.Parent.Id, t => t.Fields.Include(p => p.InternalName)));
ctx.ExecuteQuery();

//Setting Task as the Parent Content Type
SP.ContentType cTypeParent = conCollectionList.FirstOrDefault(t => t.InternalName == "Task");

SP.ContentTypeCreationInformation ctTYpeCreationInfo = new SP.ContentTypeCreationInformation();

ctTYpeCreationInfo.ParentContentType = cTypeParent;
ctTYpeCreationInfo.Name = "Piyush_ContentType";
ctTYpeCreationInfo.Group = "Piyush";
ctTYpeCreationInfo.Description = "Custom Content Type for testing";

SP.ContentType contentType = conCollectionList.Add(ctTYpeCreationInfo);

SP.Field field = ctx.Web.Fields.GetByInternalNameOrTitle("Birthday");

//Faulty code
//contentType.Fields.Add(field);

SP.FieldLinkCreationInformation fieldLink = new FieldLinkCreationInformation();
fieldLink.Field = field;
contentType.FieldLinks.Add(fieldLink);
contentType.Update(true);
           
ctx.ExecuteQuery();

The remote server returned an error: (409) Conflict from SharePoint ClientObjectModel

Problem

I got this issue for ListItem having attachments. We’re initially creating a ListItem using the Update() & ExecuteQuery() method. Next when we tried to create an attachment for the same ListItem using ExecuteQuery(), this error was thrown.

Solution

Solution was to remove the ExecuteQuery() after the ListItem Update() and use a single ExecuteQuery() for both the ListItem and its Attachment.

using System;
using IO = System.IO;
using System.Linq;
using System.Runtime.Remoting;
using System.Text;
using System.Threading;
using Microsoft.SharePoint.Client;
using SP = Microsoft.SharePoint.Client;


string siteUrl = "http://servername:12345/";
SP.ClientContext ctx = new SP.ClientContext(siteUrl);
SP.List list = ctx.Web.Lists.GetByTitle("ListTitle");

SP.ListItemCreationInformation listItemCreationInfo = new SP.ListItemCreationInformation();
SP.ListItem oListItem = list.AddItem(listItemCreationInfo);
                
//This will create ListItem before adding attachments
oListItem.Update();

//The following line should be removed
//ctx.ExecuteQuery();


string strFilePath = "FullFilePath";

byte[] bytes = IO.File.ReadAllBytes(strFilePath);

using (IO.MemoryStream mStream = new IO.MemoryStream(bytes))
{
    SP.AttachmentCreationInformation aci = new SP.AttachmentCreationInformation();
    aci.ContentStream = mStream;
    aci.FileName = IO.Path.GetFileNameWithoutExtension(strFilePath);

    oListItem.AttachmentFiles.Add(aci);

    oListItem.Update();
    ctx.ExecuteQuery();
}

The error was thrown at the last line (ctx.ExecuteQuery() in bold). Actually the List was already created above (commented ctx.ExecuteQuery()). The solution was to remove that ExecuteQuery() and bundle both the requests, create ListItem & upload attachment, in a single ExecuteQuery().

NOTE:- Do not forget to mention the oListItem.Update() as the ListItem has to be created first before adding attachments to it. Just don’t immediately call the Execute method