Why FieldLookupValue of an item can not be initialized in csom? - c#

I am going to initialize items of a sharepoint list. One of field is a lookup one, but when I'm going to initialize it, no value is set to it.
Here is my code:
var clientContext =
new ClientContext(aURL)
{
Credentials = new System.Net.NetworkCredential(somestring)
};
Web oWebsite = clientContext.Web;
List teachersList = oWebsite.Lists.GetByTitle("Teachers");
FieldLookupValue lookupField = new FieldLookupValue();
lookupField.LookupId = anInteger;
teacherInfoListItem["ProfessorID"] = lookupField;
teacherInfoListItem["Title"] = value;
teacherInfoListItem["LastName"] = value;
teacherInfoListItem.Update();
clientContext.ExecuteQuery();

Your code logic should be fine, make sure the anInteger item exists in your lookup list.
My tested code.
using(var clientContext =new ClientContext("http://sp"))
{
var web = clientContext .Web;
var oList = web.Lists.GetByTitle("TestDetails");
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem oListItem = oList.AddItem(itemCreateInfo);
FieldLookupValue lookupField = new FieldLookupValue();
lookupField.LookupId = 1;
oListItem["Title"] = "My New Item!";
oListItem["Name"] = lookupField;
oListItem.Update();
clientContext.ExecuteQuery();
Console.WriteLine("complete");
}

Related

Add item to SharePoint Online list c#

I'm having a web api which is having some data in its body and that data i want to add to SharePoint online list using c#. But below code is giving me unauth error.
using (var context = new ClientContext(siteUrl))
{
context.ExecutingWebRequest += Context_ExecutingWebRequest; // for oAuth it working in get list dat
Web web = context.Web;
List topicsList = context.Web.Lists.GetByTitle("ListName");
ListItemCreationInformation newTopicInfo = new ListItemCreationInformation();
ListItem oListItem = topicsList.AddItem(newTopicInfo);
oListItem["Title"] = "Test";
oListItem["Column1"] = "Test1";
oListItem.Update();
context.ExecuteQuery();
}
The above code is working perfectly fine now, i was missing permissions to my app. For using oAuth we have to register an Add-in in SharePoint, and to post data in sharepoint i have to give FullControl to my add-in, but while creation i have made it read-only.
Below is the referance.
Referance
For SharePoint Online, use SharePointOnlinCredentials class pass credentials to authencation:
string password = "*******";
string account = "username#tenant.onmicrosoft.com";
var secret = new SecureString();
foreach (char c in password)
{
secret.AppendChar(c);
}
using (ClientContext ctx = new ClientContext("https://tenant.sharepoint.com/sites/dev/"))
{
ctx.Credentials = new SharePointOnlineCredentials(account, secret);
ctx.Load(ctx.Web);
ctx.ExecuteQuery();
List topicsList = ctx.Web.Lists.GetByTitle("ListName");
ListItemCreationInformation oListItemCreationInformation = new ListItemCreationInformation();
ListItem oListItem = topicsList.AddItem(oListItemCreationInformation);
oListItem ["Title"] = "New List Item";
oListItem["Column1"] = "Test1";
oListItem .Update();
ctx.ExecuteQuery();
};

Should I use one or multiple ClientContext to update a very large List?

I need to update a large SharePoint List, about 10,000 items or more. Each ListItem has 4 columns to be updated. I don't know what the best approach for this scenario is:
Use 1 ClientContext, fetch ListItemCollection in batch of n rows,
loop through each ListItem and update its columns before the next
batch. Or
Fetch a list of ListItemCollectionPosition in batch of n rows, loop through each ListItemCollectionPosition, create a new ClientContext, fetch ListItemCollection and then update.
Method 1
using (ClientContext ctx = new ClientContext(url))
{
ctx.Credentials = new SharePointOnlineCredentials(username,password);
List list = ctx.Web.Lists.GetByTitle("mylist");
ctx.Load(list);
ctx.ExecuteQuery();
ListItemCollectionPosition pos = null;
CamlQuery camlQuery = new CamlQuery
{
ViewXml = "<View Scope='Recursive'><RowLimit>100</RowLimit></View>"
};
do
{
if (pos != null)
{
camlQuery.ListItemCollectionPosition = pos;
}
ListItemCollection listItemCollection = list.GetItems(camlQuery);
ctx.Load(listItemCollection);
ctx.ExecuteQuery();
pos = listItemCollection.ListItemCollectionPosition;
foreach(ListItem item in listItemCollection)
{
item["col1"] = "abc";
item["col2"] = "def";
item["col3"] = "ghi";
item["col4"] = "jkl";
item.Update();
}
ctx.ExecuteQuery();
} while (pos != null);
}
Method 2
private void UpdateList()
{
using (ClientContext ctx = new ClientContext(url))
{
ctx.Credentials = new SharePointOnlineCredentials(username,password);
List list = ctx.Web.Lists.GetByTitle("mylist");
ctx.Load(list);
ctx.ExecuteQuery();
ListItemCollectionPosition pos = null;
CamlQuery camlQuery = new CamlQuery
{
ViewXml = "<View Scope='Recursive'><RowLimit>100</RowLimit></View>"
};
List<ListItemCollectionPosition> positions = new List<ListItemCollectionPosition>();
do
{
if (pos != null)
{
camlQuery.ListItemCollectionPosition = pos;
}
ListItemCollection listItemCollection = list.GetItems(camlQuery);
ctx.Load(listItemCollection);
ctx.ExecuteQuery();
pos = listItemCollection.ListItemCollectionPosition;
positions.Add(pos);
} while (pos != null);
List<Task> tasks = new List<Task>();
foreach(var position in positions)
{
tasks.Add(UpdateItem(position));
}
Task.WaitAll(tasks.ToArray());
}
}
private Task UpdateItem(ListItemCollectionPosition pos)
{
using (ClientContext ctx = new ClientContext(url))
{
ctx.Credentials = new SharePointOnlineCredentials(username,password);
List list = ctx.Web.Lists.GetByTitle("mylist");
ctx.Load(list);
ctx.ExecuteQuery();
CamlQuery camlQuery = new CamlQuery
{
ViewXml = "<View Scope='Recursive'><RowLimit>100</RowLimit></View>"
};
camlQuery.ListItemCollectionPosition = pos;
ListItemCollection listItemCollection = list.GetItems(camlQuery);
ctx.Load(listItemCollection);
ctx.ExecuteQuery();
foreach(ListItem item in listItemCollection)
{
item["col1"] = "abc";
item["col2"] = "def";
item["col3"] = "ghi";
item["col4"] = "jkl";
item.Update();
}
return ctx.ExecuteQueryAsync();
}
}
In method 1 and 2 I would set ViewFields to limit amount of data that is transfered.
In method 2 UpdateItem method is executed after positions collection is full. Why not updating list items while positions collection is being populated - You could implement enumerator with yield attribute.
public static IEnumerable<ListItemCollectionPosition> GetPositions()
{
do
{
...
yield return pos;
...
} while (pos != null);
}

How to retrieve list items from SharePoint 2013

At work we had to move from SharePoint 2010 to 2013 and my code for retrieving list items doesn't work anymore. Here is my code for SP 2010:
com.mycompany.intranet.Lists listService = new com.mycompany.intranet.Lists();
listService.Credentials = System.Net.CredentialCache.DefaultCredentials;
listService.Url = "url";
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
string listName = cbxMailDistributionList.SelectedValue.ToString();
string viewName = "";
string rowLimit = "0";
System.Xml.XmlElement query = xmlDoc.CreateElement("Query");
System.Xml.XmlElement viewFields = xmlDoc.CreateElement("ViewFields");
System.Xml.XmlElement queryOptions = xmlDoc.CreateElement("QueryOptions");
viewFields.InnerXml = "<FieldRef Name='Title' />";
System.Xml.XmlNode nodeListItems =
listService.GetListItems(listName, viewName, query, viewFields, rowLimit, queryOptions, null);
xmlDoc.LoadXml(nodeListItems.InnerXml);
xlNodeList rows = xmlDoc.GetElementsByTagName("z:row");
List<string> recipients = new List<string>();
foreach (XmlNode attribute in rows)
{
if(attribute.Attributes["ows_Title"].Value == null){}
else {
if (recipients.Contains(attribute.Attributes["ows_Title"].Value)){}
else {
recipients.Add(attribute.Attributes["ows_Title"].Value);
}
}
}
recipients.Sort();
distributionList = recipients;
Can you please help me to get it working with a SharePoint 2013 list again?
URL has already been updated but i get the following error: https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=DE-DE&k=k(EHNullReference);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.0);k(DevLang-csharp)&rd=true
But the list has no empty fields.
listName
is the ID of the list element.
Please help.
Thanks in advance!
Finally it works again with this code:
List<string> recipients = new List<string>();
string siteURL = #"myurl/";
ClientContext cc = new ClientContext(siteURL);
cc.Credentials = System.Net.CredentialCache.DefaultCredentials;
Web web = cc.Web;
List list = web.Lists.GetById(new Guid(cbxMailDistributionList.SelectedValue.ToString()));
CamlQuery caml = new CamlQuery();
ListItemCollection items = list.GetItems(caml);
cc.Load<List>(list);
cc.Load<ListItemCollection>(items);
cc.ExecuteQuery();
foreach (Microsoft.SharePoint.Client.ListItem item in items)
{
if(item.FieldValues["Title"] == null) { }
else
{
if (recipients.Contains(item.FieldValues["Title"].ToString())) { }
else
{
recipients.Add(item.FieldValues["Title"].ToString());
}
}
}
recipients.Sort();
distributionList = recipients;
}
else
{
distributionList = null;
}
New day, new luck. Sorry for the prematurely posting of this question. I should have slept on it for a night. ;)
BR

Search user by profile property

How i can search by profile property? MSDN say use ProfileSearchManager, but it not working.
I want search users by MobilePhone property.
SPServiceContext serviceContext = SPServiceContext.GetContext(site);
UserProfileManager upm = new UserProfileManager(serviceContext);
ProfileSearchManager sp = ProfileSearchManager.GetProfileSearchManager(serviceContext);
string[] searchPattern = { "123" };
ProfileBase[] searchResults = sp.Search(searchPattern, ProfileSearchFlags.User);
foreach (ProfileBase profile in searchResults)
{
Console.WriteLine(profile.DisplayName);
}
using (SPSite site = new SPSite(siteUrl))
{
using (var qRequest = new KeywordQuery(site)
{
QueryText = "MobilePhone:*" +"123" ,
EnableQueryRules = true,
EnableSorting = false,
SourceId = new Guid("Enter here Result Source Guid"),
TrimDuplicates = false
})
{
//Get properties you want here
qRequest.SelectProperties.Add("FirstName");
qRequest.SelectProperties.Add("LastName");
SearchExecutor e = new SearchExecutor();
ResultTableCollection rt = e.ExecuteQuery(qRequest);
var tab = rt.Filter("TableType", KnownTableTypes.RelevantResults);
var result = tab.FirstOrDefault();
DataTable resultTable = result.Table;
}
}

List Template not getting applied to the new Sharepoint list

A SharePoint list is being created using Sharepoint.client but the template is not getting applied. I don't see any fields/columns in the new list. A similar questions was asked here but it's answer did not work for me. Any help is greatly appreciated!
using (ClientContext context = new ClientContext(SITE))
{
Web web = context.Web;
context.Load(web);
context.ExecuteQuery();
ListTemplate template = null;
ListTemplateCollection ltc = context.Site.GetCustomListTemplates(web);
//ListTemplateCollection ltc2 = web.ListTemplates;
context.Load(ltc);
context.ExecuteQuery();
foreach (ListTemplate t in ltc)
{
if (t.Name == "My_Template")
{
template = t;
break;
}
}
var listCreationInfo = new ListCreationInformation
{
Title = "Test_List",
Description = "Test"
};
//ListTemplate listTemplate = ltc.First(listTemp => listTemp.Name.Contains("My_Template"));
listCreationInfo.TemplateFeatureId = template.FeatureId;
listCreationInfo.TemplateType = template.ListTemplateTypeKind;
listCreationInfo.QuickLaunchOption = QuickLaunchOptions.On;
List oList = web.Lists.Add(listCreationInfo);
context.ExecuteQuery();
}

Categories