I want to update "created by" column in sharepoint. For this, i have to do using CSOM only as i do not have sharepoint server dll. I wrote code in this...
ClientContext cc = new ClientContext ("http://sharepoint...");
List list = cc.web.Lists.GetByTitle("sharepointlistname");
cc.Load(list);
ListItem item = list.GetItemById(13);//In this case, i want to update only id=13. I want to know code for all records also.
cc.Load(item);
cc.ExecuteQuery();
item("Created by") = "Dinesh";
item.Update();
When I run above code, am getting this error...
sharepoint list Invalid data has been used to update the list item. The field you are trying to update may be read only
The Created By field internal name is Author and it's a Person field, please update like this:
ClientContext ctx = new ClientContext("http://sp/sites/dev");
List list = ctx.Web.Lists.GetByTitle("MyList");
Microsoft.SharePoint.Client.CamlQuery camlQuery = new CamlQuery();
//CamlQuery to filter items which created in Today
camlQuery.ViewXml =
#"<View>
<Query>
<Where><Eq><FieldRef Name='Created' /><Value Type='DateTime'><Today /></Value></Eq></Where>
</Query>
</View>";
ListItemCollection items = list.GetItems(camlQuery);
ctx.Load(items);
ctx.ExecuteQuery();
User theUser = ctx.Web.EnsureUser("Contoso\\Jerry");
ctx.Load(theUser);
ctx.ExecuteQuery();
foreach (var item in items)
{
item["Editor"] = theUser;
item["Author"] = theUser;
item.Update();
}
ctx.ExecuteQuery();
In my project, i have to show all the name of items of the Library path that user give me. If no folder the library contains => no problem.
However, there are many folders, sub-folders, sub-sub-folders, sub^n-folders. I cannot loop all the folders, which get a endless loop. I don't need the code that i just need the concept of how to loop all folders.
Therefore, i need help from all of you experienced programmer.
The result should be:
item name folder name
---------------------------------------------
item1
item2
item1 subF1
item1 subF2
item1 subF2sub1
.
.
My idea:
// path of library and folder is URL. For example, http://example.com/libraryName/subF2/subF2sub1/item1
//if i get all folders'path, i can then get the file name by those paths.
// i won't paste my code here because there are >100 lines.
void checkFolderExist(libraryPathByUser)
{
if("folderInLibrary" != nil)
{
foreach (var folder in library)
{
string folderPath = getFolderPath(folder);
strList.Add(folderPath);
// so, how about sub-folder in the folder?
}
}
}
You can create a SPQuery object and set its Scope attribute to RecursiveAll, for example:
SPQuery query = new SPQuery();
SPFolder folder = get the folder object by folder path
query.Folder = folder;
query.ViewXml = "<View Scope=\"RecursiveAll\"><Query>your query goes here</Query></View>";
SPListItemCollection items = yourLibrary.GetItems(query);
Dictionary<string, List<SPListItem>> folderItems = new Dictionary<string, SPListItem[]>();
foreach (SPListItem item in items)
{
// If items are files
SPFile file = item.Web.GetFile(item.Url);
string folderName = file.ParentFolder.Name;
if (!folderItems.ContainsKey(folderName))
{
folderItems[folderName] = new List<SPListItem>();
}
folderItems[folderName].Add(item);
}
Following code will recursively search all the artifacts and store in listItem object. It is using csom though.
ClientContext clientContext = new ClientContext("http://Servername/");
List sharedDocumentsList = clientContext.Web.Lists.GetByTitle("Shared Documents");
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml =
#"<View Scope='Recursive' />";
ClientOM.ListItemCollection listItems =
sharedDocumentsList.GetItems(camlQuery);
clientContext.Load(listItems);
clientContext.ExecuteQuery();
foreach (var item in listItems)
{
}
Not sure if you are looking for Clientside code or not.
I'm working in a webpart. I filter (with caml) a SharePoint list and put my results in a List<SPListItem>.
Now, i need to populate another SharePoint List (I created that list in the same code) and i can't find the way to do that.
List<SPListItem> results = new List<SPListItem>() //results have the result of my query
.
.
.
SPList listFiltered = mySite.Lists[newListName]; //listFiltered is my newlist
SPListItemCollection newListItems = listFiltered.Items; //newListItem are the item from my list
foreach (SPListItem item in results)
{
//I don't know how to send my result to my SharePoint list :(
}
You will need to define your other List, then you can add a new SPListItem to that list with the columns that list contains. I am not sure what results is, if that is a typo or not, but I included that in my answer. You would need to change that if results does not exist.
SPList secondList = web.Lists["MyList"];
foreach(SPListItem item in results)
{
SPListItem Item = secondList.Items.Add();
item["Title"] = companyName
item["DateReceived"] = System.DateTime.Now;
item["Description"] = companyDesc;
item.Update();
}
I'm working on one of my first projects. I have a listbox where I select multiple values and I would like to add each selection (selectedItem.Text) to a list of strings.
so far what I was working on is something like ..
selectedItem = new List<string>();
var value = lstpdfList.SelectedItem.Text;
for (int i = 0; i < lstpdfList.SelectedValue.Count(); i++)
{
selectedItem.Add(value);
}
I would really appreciate any advice.
Iterate each item from ListBox.Items collection
foreach (ListItem item in ListBox1.Items)
{
if (item.Selected)
{
selectedItem.Add(item.Text); // selectedImte.Add(item.Value);
}
}
There is SelectedItems property of ListBox, try to iterate throught it. For example, if there is strings in your ListBox, then your code might look like this:
selectedItem = new List<string>();
foreach (string value in lstpdfList.SelectedValues)
selectedItem.Add(value);
You can just cast them to strings:
var selectedItems = listBox1.SelectedItems
.Cast<string>()
.ToList();
If you have populated your ListBox with something other than just strings, just cast to whichever type you need, like so:
var selectedItems = listBox1.SelectedItems
.Cast<WhateverYourTypeIs>()
.Select(item => item.ToString())
.ToList();
In code how can I access a list e.g "MyList" in sharepoint,
then iterate through this list items and get the value of a particular column on that list e.g the "URL" column?
To retrieve all items from a list and iterate through each one, the best solution would be as follows (assuming that this code is run as part of a feature):
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
using(SPSite site = properties.Feature.Parent as SPSite)
{
SPList list = site.RootWeb.Lists["ListName"];
SPListItemCollection items = list.Items;
foreach (SPListItem listItem in items)
{
Response.Write(SPEncode.HtmlEncode(listItem["Url"].ToString()) +"<BR>");
}
}
}
But if the list is very large, it would be better to paginate through the list items:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
using(SPSite site = properties.Feature.Parent as SPSite)
{
SPList list = site.RootWeb.Lists["ListName"];
if(items.ItemCount > 100)
{
SPQuery query = new SPQuery();
query.RowLimit = 100;
int index = 1;
do
{
SPListItemCollection items = list.GetItems(query);
foreach (SPListItem listItem in items)
{
Response.Write(SPEncode.HtmlEncode(listItem["Url"].ToString()) +"<BR>");
}
query.ListItemCollectionPosition = items.ListItemCollectionPosition;
index++;
} while (query.ListItemCollectionPosition != null);
}
else
{
SPListItemCollection items = list.Items;
foreach (SPListItem listItem in items)
{
Response.Write(SPEncode.HtmlEncode(listItem["Url"].ToString()) +"<BR>");
}
}
}
}
This is based on the Microsoft's Best Practices for SharePoint.
From this blog post:
The correct way to do it is to store the Items property return value in a SPListItemCollection variable. With this the database is only queried once and we will then iterate over the result set that is stored within the collection object. Here is the changed sample code:
SPListItemCollection items = SPContext.Current.List.Items;
for(int i=0;i<100 && i<items.Count;i++) {
SPListItem listItem = items[i];
htmlWriter.Write(listItem["Title"]);
}
You can also iterate the items directly, and if you're using a URL field you probably want to use the SPFieldUrlValue class, so you don't have to deal with the way SharePoint stores URLs:
foreach(SPListItem item in spList.Items){
SPFieldUrlValue data = item["Url"] as SPFieldUrlValue;
// now you have data.Description, data.Url
}
There are many such SPField* helper classes, and they are very useful, specially when you have multiple values.
Edit:
For some reason some people believe this way is slower, based on the evidence in the blog post of on Greg's post (even got down voted). This, however, has nothing to do with my answer: a foreach loop creates an Iterator, so it shouldn't access the database 99 more times (on the post they used a for loop to access the first 100 items).
if you are in a feature, the feature is activated at a specific scope, (e.g. Site, Web, WebApplication or Farm).
When you want to access a list from the feature, use the SPFeatureReceiver class to bind an event receiver to your feature. Then, in that class, there are overrides for when the feature activated event is triggered. that override receives a parameter of type SPFeatureReceiverProperties.
from that parameter, you can use get into a site:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
using(SPSite site = properties.Feature.Parent as SPSite) //this depends on scope of feature
{
SPList myList = site.RootWeb.Lists["MyList"];
}
}
for how the iterate that list, see the orther answers
I know this question was asked a very long time ago but I hope I am able to help someone out now :)
This is how I was able to accomplish this,
protected void Page_Load(object sender, EventArgs e)
{
// Get the current domain
var current = HttpContext.Current.Request.Url.Host;
// We need to tell the SPSite object the URL of where our List is stored.
// Make sure you have the right location placed after the 'current' variable
using (SPSite spSite = new SPSite("http://"+current+"/DirectoryForLists/Lists"))
{
// Returns the Web site that is located at the specified server-relative or site-relative URL.
using (SPWeb spWeb = spSite.OpenWeb())
{
//Get our list we created.
SPList list = spWeb.Lists["Name Of the List"];
// Create a new SPQuery object that will hold our CAML query.
SPQuery q = new SPQuery();
// CAML query.
// This allows you to controll how you receieve your data.
// Make the data ASC or DESC. Find more on MSDN.
q.Query = "<OrderBy><FieldRef Name='DESCR' Ascending='TRUE' /></OrderBy>";
// We put our list data into a SP list Item Collection.
// Notice that the CAML query is the only parameter for the GetItems() function.
SPListItemCollection items = list.GetItems(q);
// Here you can loop through your list.
foreach (SPListItem spItem in items)
{
// Your code here.
MessageBox(spItem);
// Get URL column
MessageBox(spItem["URL"]);
// Another Column
MessageBox(spItem["DateTime"]);
}
}
}
}
Below is the best option to iterate
SPList list = web.Lists[listname];
SPQuery query = new SPQuery();
query.Query = "<OrderBy><FieldRef Name='ID' /></OrderBy>";
//Scope="Recursive" retrieves items from all folders and subfolders in a list
query.ViewFields = "<FieldRef Name='" + Lists.MRPLibrary.RebateClaimed + "' /><FieldRef Name='ID'/>";
query.ViewAttributes = "Scope=\"RecursiveAll\"";
query.RowLimit = 100;
do
{
SPListItemCollection items = list.GetItems(query);
foreach (SPListItem listItem in items)
{
}
query.ListItemCollectionPosition = items.ListItemCollectionPosition;
} while (query.ListItemCollectionPosition != null);
}
Below code used to delete all bulk list items and here can skip latest 150 items to delete.
Iterating through SPListItemCollection and very quick time like 3000 items will be delete in 2 mints.
SPList list = web.Lists["DemoDelete"];
SPListItemCollection collListItems = list.GetItems();
var watch = System.Diagnostics.Stopwatch.StartNew();
Console.WriteLine("Start Time: " + watch);
//delete all items uncomment this code
//foreach (SPListItem item in collListItems)
//{
// SPListItem delItem = list.GetItemById(item.ID);
// Console.WriteLine("Item Deleted" + delItem.ID);
// delItem.Delete();
// list.Update();
//}
//skip lastest 150 items
for (int i = collListItems.Count - 150; i >= 0; i--)
{
SPListItem listItem = list.GetItemById(collListItems[i].ID); //collListItems[i];
Console.WriteLine("Item Deleted" + listItem.ID);
listItem.Delete();
list.Update();
}
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
Console.WriteLine("End Time: " + elapsedMs);
As others have said, you shouldn´t iterate the Items collection directly (especially in large collections). Here´s an alternaltive:
// if you need the whole collection. Otherwise use SPQuery on the list
DataTable dt = list.Items.GetDataTable();
foreach (DataRow row in dt.Rows)
{
...
Then you can do numerous things. If you need to do a check to get only some of the items, ex:
if (row["ContentType"].ToString().Equals("Your contenttype id"))
{
SPListItem item = list.GetItemById((int)row["ID"]);
or use the SpQuery to get your column in the query, like:
SPQuery oQuery = new SPQuery();
oQuery.ViewFields = "<FieldRef Name='UrlColumn'/>";
list.Items.GetItems(oQuery).GetDataTable();
...foreach code...
row["UrlColumn"]
If you are in a x86 environment I've recently discovered an awesomely read-only way to get at the data with MSSQL/OLEDB...
SELECT * FROM OPENROWSET (
'Microsoft.ACE.OLEDB.12.0',
'WSS;IMEX=1;RetrieveIds=Yes;DATABASE=http://sharepoint.lsi.local/ops/;LIST={3DCAF100-44A1-4331-8328-748AA98E36AB};',
'SELECT * FROM list'
)
http://www.connectionstrings.com/sharepoint
BTW
When using OPENROWSET...
IMEX=2 is for Read/Write. IMEX=1 is ReadOnly.
List = [Name] works for me instead of needing to use the list={GUID}.