Update Exclusive properties[AllowMultiResponses & ShowUser] of a Survey List for SharePoint using service and CSOM C#

Survey List for SharePoint is like any other List except that its got some exclusive properties:

  • ShowUser – Indicates whether to display the user’s name along side its response. Default value is True.
  • AllowMultiResponses – Indicates whether an user can post multiple response for a Survey. Default value is False.

Now usually to update other common properties of a List, like Title, etc., we can easily rely on CSOM. However, there’s no such provision for these two properties or any other exclusive properties of any other List. Here, we’ll be focussing on the Survey List only.So when the Client Object Model fails, turn to services. The service Lists.asmx, comprises of many methods related to Lists. One of the method is UpdateList. This method has the following definition:

[SoapDocumentMethodAttribute("http://schemas.microsoft.com/sharepoint/soap/UpdateList", RequestNamespace="http://schemas.microsoft.com/sharepoint/soap/", ResponseNamespace="http://schemas.microsoft.com/sharepoint/soap/", Use=SoapBindingUse.Literal, ParameterStyle=SoapParameterStyle.Wrapped)] 
public XmlNode UpdateList (
    string listName,
    XmlNode listProperties,
    XmlNode newFields,
    XmlNode updateFields,
    XmlNode deleteFields,
    string listVersion
)

The XmlNode parameter listProperties, is the one I’ll be focusing at. This will be in the format of a

XmlNode where we can update/modify the following properties:
AllowMultiResponses TRUE to allow multiple responses to the survey.
Description A string that contains the description for the list.
Direction A string that contains LTR if the reading order is left-to-right, RTL if it is right-to-left, or None.
EnableAssignedToEmail TRUE to enable assigned-to e-mail for the issues list.
EnableAttachments TRUE to enable attachments to items in the list. Does not apply to document libraries.
EnableModeration TRUE to enable Content Approval for the list.
EnableVersioning TRUE to enable versioning for the list.
Hidden TRUE to hide the list so that it does not appear on the Documents and Lists page, Quick Launch bar, Modify Site Content page, or Add Column page as an option for lookup fields.
MultipleDataList TRUE to specify that the list in a Meeting Workspace site contains data for multiple meeting instances within the site.
Ordered TRUE to specify that the option to allow users to reorder items in the list is available on the Edit View page for the list.
ShowUser TRUE to specify that names of users are shown in the results of the survey.
Title A string that contains the title of the list.

As you can see the two exclusive properties of the List Survey, ShowUser & AllowMultiResponses are present here which is exactly what we need. The other properties can also be updated using the CSOM so I won’t be using them here.

One important thing, this method simultaneously, also creates, updates, & deletes Fields/SiteColumns for the given List. However, if you don’t want to use them (as will be the case here) you can pass an empty string as parameters.

Following is the code sample to accomplish this task. The first part demonstrates how to construct the parameter, listProperties.

Desired Format
<List Title=”List_Name” Description=”List_Description” Direction=”LTR”/>

XmlDocument xmlDoc = new System.Xml.XmlDocument();
XmlNode ndProperties = xmlDoc.CreateNode(XmlNodeType.Element, "List", "");
XmlAttribute ndTitleAttrib = (XmlAttribute)xmlDoc.CreateNode(XmlNodeType.Attribute, "Title", "");
XmlAttribute ndDescriptionAttrib = (XmlAttribute)xmlDoc.CreateNode(XmlNodeType.Attribute, "Description", "");
XmlAttribute ndDirectionAttrib = (XmlAttribute)xmlDoc.CreateNode(XmlNodeType.Attribute, "Direction", "");
XmlAttribute ndMultiresponse = (XmlAttribute)xmlDoc.CreateNode(XmlNodeType.Attribute, "AllowMultiResponses", "");
XmlAttribute ndShowUser = (XmlAttribute)xmlDoc.CreateNode(XmlNodeType.Attribute, "ShowUser", "");

ndTitleAttrib.Value = "My Survey";
ndDescriptionAttrib.Value = "Allowing multiple responses for this Survey";
ndDirectionAttrib.Value = "LTR";
ndMultiresponse.Value = "TRUE";
ndShowUser.Value = "TRUE";

ndProperties.Attributes.Append(ndTitleAttrib);
ndProperties.Attributes.Append(ndDescriptionAttrib);
ndProperties.Attributes.Append(ndDirectionAttrib);
ndProperties.Attributes.Append(ndMultiresponse);
ndProperties.Attributes.Append(ndShowUser);

So basically we're creating the following node

<
List Title="My Survey" Description="Allowing multiple responses for this Survey" Direction="LTR" AllowMultiResponses="TRUE" ShowUser="TRUE"/>

Finally, we’re going to use this parameter in the UpdateList method. The following code is a sample demonstration to call this method from the Lists.asmx service. Note that since this service is dependant on the site’s url, it will always vary from site to site. Hence we’re setting the url of the web service at runtime. One more thing, all the parameters that will be passed should be string i.e., the OuterXml property for XmlNode parameters.

string webServiceUrl = ctx.Web.Url + "/_vti_bin/Lists.asmx";

StringBuilder sbEnvelope = new StringBuilder();
sbEnvelope.Append("");
sbEnvelope.Append("");
sbEnvelope.Append(String.Format(
    "" +
        "" +
            "{0}" +
            "{1}" +
            "{2}" +
            "{3}" +
            "{4}" +
            "{5}" +
        "" +
    ""
    , id, ndProperties.OuterXml, String.Empty, String.Empty, String.Empty, version));
sbEnvelope.Append("");

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(webServiceUrl);
req.Method = "POST";
req.ContentType = "text/xml; charset=\"utf-8\"";
req.Accept = "text/xml";
req.Headers.Add("SOAPAction", "\"http://schemas.microsoft.com/sharepoint/soap/UpdateList\"");
req.UserAgent = "FrontPage";
req.UseDefaultCredentials = false;

Uri targetSite = new Uri(ctx.Web.Url);
SharePointOnlineCredentials spCredentials = (SharePointOnlineCredentials)ctx.Credentials;
string authCookieValue = spCredentials.GetAuthenticationCookie(targetSite);
req.CookieContainer = new CookieContainer();
req.CookieContainer.Add(
    new Cookie("FedAuth",
        authCookieValue.TrimStart("SPOIDCRL=".ToCharArray()),
        String.Empty,
        targetSite.Authority));

using (IO.Stream stream = req.GetRequestStream())
{
    using (IO.StreamWriter writer = new IO.StreamWriter(stream))
    {
        writer.Write(sbEnvelope.ToString());
    }
}

WebResponse response = req.GetResponse();
using (IO.Stream responseStream = response.GetResponseStream())
{
    XmlDocument xDoc = new XmlDocument ();
    xDoc.Load(responseStream);

    if (xDoc.DocumentElement != null && xDoc.DocumentElement.InnerText.Length > 0)
    {
        Debug.WriteLine(String.Concat(DateTime.Now.ToShortTimeString(), " Response of the Survey List Update: ", xDoc.DocumentElement.InnerText));
    }
}

Here’s a screen-shot of the UpdateList method. You can view your site’s service at your site’s url + “_vti_bin/Lists.asmx”

Create Promoted Links/My Report Library/Asset Library list in SharePoint 2013 using Client Object Model C#

I have already written a blog specifying how to create a List for SharePoint using Client Object Model. You can check that here.Though that code worked for most of the Lists, the List, Promoted Links, Report Library, and Asset Library, could not be created. They were constantly throwing the error, Invalid list template! As far as I was concerned, ListTemplates that were passed to the ListCreationInformation were correct. So why this error?? Here, I must also mention that I was trying to create these Lists on the Web template Team-Site.

The problem was I was only passing the baseTemplate to it. However, for these Lists, I needed to mention the GUID of the Feature, that contained the schema of the new List. Following is the modified code.

Namespace:

using Microsoft.SharePoint.Client;

//use one of the templateName that suits your purpose
string templateName = "Promoted Links";string templateName = "Report Library";string templateName = "Asset Library";

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

Web web = ctx.Web;

// Get the list template by name
ListTemplate listTemplate = web.ListTemplates.GetByName(templateName);

ctx.Load(listTemplate);
ctx.ExecuteQuery();

// Create a new object for ListCreationInformation class - used to specify the // properties of the new list
ListCreationInformation creationInfo = new ListCreationInformation();

// Specify the title of your List
creationInfo.Title = "My Custom List";

// Specify the list description, if any
creationInfo.Description = "Description";

// Set a value that specifies the feature identifier of the feature 
// that contains the list schema for the new list.
creationInfo.TemplateFeatureId = listTemplate.FeatureId;

// Set a value that specifies the list server template of the new list
creationInfo.TemplateType = listTemplate.ListTemplateTypeKind;

web.Lists.Add(creationInfo);
ctx.ExecuteQuery();
  

List of SharePoint Lists BaseTemplateType

SharePoint has many Lists. Following is a list of BaseTemplateType of some of the SharePoint List that I know for a quick reference.

Notused -1
NoListTemplate 0
GenericList 100
DocumentLibrary 101
Survey 102
Links 103
Announcements 104
Contacts 105
Events 106
Tasks 107
DiscussionBoard 108
PictureLibrary 109
DataSources 110
WebTemplateCatalog 111
UserInformation 112
WebPartCatalog 113
ListTemplateCatalog 114
XMLForm 115
MasterPageCatalog 116
NoCodeWorkflows 117
WorkflowProcess 118
WebPageLibrary 119
CustomGrid 120
SolutionCatalog 121
NoCodePublic 122
ThemeCatalog 123
DesignCatalog 124
AppDataCatalog 125
DataConnectionLibrary 130
WorkflowHistory 140
GanttTasks 150
HelpLibrary 151
AccessRequest 160
PromotedLinks 170
TasksWithTimelineAndHierarchy 171
MaintenanceLogs 175
Meetings 200
Agenda 201
MeetingUser 202
Decision 204
MeetingObjective 207
TextBox 210
ThingsToBring 211
HomePageLibrary 212
Posts 301
Comments 302
Categories 303
Facility 402
Whereabouts 403
CallTrack 404
Circulation 405
Timecard 420
Holidays 421
StatusList 432
ReportLibrary 433
IMEDic 499
Microfeed 544
AnnouncementTiles 563
ExternalList 600
MySiteDocumentLibrary 700
PublishingPageLibrary 850
AssetLibrary 851
IssueTracking 1100
AdminTasks 1200
HealthRules 1220
HealthReports 1221
DeveloperSiteDraftApps 1230
PersonalDocumentLibrary 2002
PrivateDocumentLibrary 2003
AccessApp 3100
Sharing Links 3300
wfsvc 4501

Again it’s not a complete list, it’s just a list of all the SharePoint List BaseTemplateType that I am aware of. I might have to further modify it in the future.


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();

Create, Update, Delete a SharePoint List and add a new Field using Client Object Model

Create and update a SharePoint list

// Starting with ClientContext, the constructor requires a URL to the 
// server running SharePoint. 
ClientContext context = new ClientContext("http://SiteUrl"); 

// The SharePoint web at the URL.
Web web = context.Web; 

ListCreationInformation creationInfo = new ListCreationInformation(); 
creationInfo.Title = "My List"; 
creationInfo.TemplateType = (int)ListTemplateType.Announcements; 
List list = web.Lists.Add(creationInfo); 
list.Description = "New Description"; 

list.Update(); 
context.ExecuteQuery(); 

Delete a SharePoint list

// Starting with ClientContext, the constructor requires a URL to the 
// server running SharePoint. 
ClientContext context = new ClientContext("http://SiteUrl"); 

// The SharePoint web at the URL.
Web web = context.Web; 

List list = web.Lists.GetByTitle("My List"); 
list.DeleteObject(); 

context.ExecuteQuery();  

Add a field to a SharePoint list

This example adds a field to a SharePoint list. add an alias to the using statement for Microsoft.SharePoint.Client namespace so you can refer to its classes unambiguously. For example,

using SP = Microsoft.SharePoint.Client;
// Starting with ClientContext, the constructor requires a URL to the 
// server running SharePoint. 
ClientContext context = new ClientContext("http://SiteUrl"); 

SP.List list = context.Web.Lists.GetByTitle("Announcements"); 

SP.Field field = list.Fields.AddFieldAsXml("", 
 true, 
 AddFieldOptions.DefaultValue); 

SP.FieldNumber fldNumber = context.CastTo<FieldNumber>(field); 
fldNumber.MaximumValue = 100; 
fldNumber.MinimumValue = 35; 
fldNumber.Update(); 

context.ExecuteQuery();