CAML query to get items from SPList - c#

I wanted to update the Name field in a list which contain 'finance' in the department list. I wrote the following code but it updates every item in the Name column whether it contains 'finance' or not.
What am i doing wrong?
SPListItemCollection Items = RiskAssesment.GetItems(new SPQuery()
{
Query = #"<where>
<Eq>
<FiledRef Name 'Department'/>
<Value Type='Text'>Finance </Value>
</Eq>
</Where>"
});
foreach (SPListItem item in Items)
{
item["Name"] = "abcdef";
item.Update();
}

FiledRef should be FieldRef. And you forgot the equal sign, it should be like this:
<FieldRef Name='Department' />
Small edit:
I'm not sure if CAML is case-sensitive, but in case it is: change the opening-where to <Where>.

SPListItemCollection Items = RiskAssesment.GetItems(new SPQuery()
{
Query = #"<Where>
<Eq>
<FieldRef Name='Department'/>
<Value Type='Text'>Finance </Value></Eq></Where>"
});
foreach (SPListItem item in Items)
{
item["Name"]="abcdef";
item.Update();
}

The below function get the folder name and id of subfolder where items stored
folder = item.folder.
Initially it will be null.
static string GetParentFolder(SPListItem itemToFind, SPFolder folder)
{
SPQuery query = new SPQuery();
// query.Query = "<OrderBy><FieldRef Name='Title'/></OrderBy>";
query.Query = "<Where><Eq><FieldRef Name=\"ID\"/><Value Type=\"Integer\">"+ itemToFind.ID +"</Value></Eq></Where>";
query.Folder = folder;
query.ViewAttributes = "Scope=\"Recursive\"";
SPListItemCollection items = itemToFind.ParentList.GetItems(query);
int intpartentFolderID=0 ;
if (items.Count > 0)
{
foreach (SPListItem item in items)
{
SPFile f = item.Web.GetFile(item.Url);
string test11 = f.ParentFolder.Name;
intpartentFolderID = f.ParentFolder.Item.ID;
//string test1 = item.File.ParentFolder.Name;
return (intpartentFolderID.ToString());
}
}
return (intpartentFolderID.ToString());
}

So I just came across this older post, and I don't have enough reputation to comment on the selected answer.
But I know that when using CAML is definitely case sensitive in SharePoint 2013.
Just means that the opening <where> should be <Where>.
Hope you got your issue solved!

The below function get the folder name and id of subfolder where items stored
folder = item.folder.
Initially it will be null.
static string GetParentFolder(SPListItem itemToFind, SPFolder folder)
{
SPQuery query = new SPQuery();
// query.Query = "<OrderBy><FieldRef Name='Title'/></OrderBy>";
query.Query = "<Where><Eq><FieldRef Name=\"ID\"/><Value Type=\"Integer\">"+ itemToFind.ID +"</Value></Eq></Where>";
query.Folder = folder;
query.ViewAttributes = "Scope=\"Recursive\"";
SPListItemCollection items = itemToFind.ParentList.GetItems(query);
int intpartentFolderID=0 ;
if (items.Count > 0)
{
foreach (SPListItem item in items)
{
SPFile f = item.Web.GetFile(item.Url);
string test11 = f.ParentFolder.Name;
intpartentFolderID = f.ParentFolder.Item.ID;
//string test1 = item.File.ParentFolder.Name;
return (intpartentFolderID.ToString());
}
}
return (intpartentFolderID.ToString());
}
Thanks
Deva- Cheraideva

Related

how to get modifiedby property of a file for showing file details sharepoint C#

I want to display files from a sharepoint folder that were modified by username. please help me for this. Also tell me how to show this file with sorting order by datetime.
I tried using
docName.Add(file.ModifiedBy);
property but its not available, here is the code:
public List<string> getFiles(ClientContext CContext,string INVOICENO)
{
List list = CContext.Web.Lists.GetByTitle("Documents");
CContext.Load(list);
CContext.Load(list.RootFolder);
CContext.Load(list.RootFolder.Folders);
CContext.Load(list.RootFolder.Files);
CContext.ExecuteQuery();
FolderCollection fcol = list.RootFolder.Folders;
List<string> docName = new List<string>();
foreach (Folder f in fcol)
{
if(INVOICENO==null)
{
INVOICENO = "";
}
string foldername = INVOICENO.ToString();
if (f.Name == foldername)
{
CContext.Load(f.Files);
CContext.ExecuteQuery();
FileCollection fileCol = f.Files;
foreach (File file in fileCol)
{
docName.Add(file.Name);
docName.Add(file.TimeLastModified.ToShortDateString());
}
}
}
return docName.ToList();
}
According to my testing and research, you can use CAML Query to display the files modified by the username from the SharePoint folder.
Here is an example you can refer to:(sorted by modification time in ascending order)
static void Main(string[] args)
{
var clientContext = GetonlineContext();
Web site = clientContext.Web;
List list = clientContext.Web.Lists.GetByTitle("Library Name");
CamlQuery query = new CamlQuery();
query.ViewXml = "<View><Query><Where><Eq><FieldRef Name='Editor' /><Value Type='User'>UserName</Value></Eq></Where><OrderBy><FieldRef Name='Modified' Ascending='True' /></OrderBy></Query><ViewFields /><QueryOptions /></View>";
ListItemCollection collListItem = list.GetItems(query);
clientContext.Load(collListItem);
clientContext.ExecuteQuery();
foreach (ListItem item in collListItem)
{
Debug.WriteLine("Name:"+item["FileLeafRef"]+"\n"+"Modified"+item["Modified"]);
}
clientContext.ExecuteQuery();
}

C# Sharepoint.Client - Return all files and folders from a given subfolder

I am trying to return all files and folders in a SharePoint library starting from a given subfolder.
If I set the FolderServerRelativeUrl on the CamlQuery to the folder i wish to start from, I can get all the list items for that given folder; however, when I try to add in camlQuery.ViewXML to recursively return items with any additional sub folders as well, I get the following exception:
Microsoft.SharePoint.Client.ServerException: 'The attempted operation is prohibited because it exceeds the list view threshold enforced by the administrator.'
Code
public static IEnumerable<string> GetSharepointFiles2(string sharePointsite, string libraryName, string username, string password, string subFolders)
{
Uri filename = new Uri(sharePointsite);
string server = filename.AbsoluteUri.Replace(filename.AbsolutePath, "");
List<string> fullfilePaths = new List<string>();
using (ClientContext cxt = new ClientContext(filename))
{
cxt.Credentials = GetCreds(username, password);
Web web = cxt.Web;
cxt.Load(web, wb => wb.ServerRelativeUrl);
cxt.ExecuteQuery();
List list = web.Lists.GetByTitle(libraryName);
cxt.Load(list);
cxt.ExecuteQuery();
Folder folder = web.GetFolderByServerRelativeUrl(web.ServerRelativeUrl + subFolders);
cxt.Load(folder);
cxt.ExecuteQuery();
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = #"<View Scope='RecursiveAll'>
<Query>
</Query>
</View>";
camlQuery.FolderServerRelativeUrl = folder.ServerRelativeUrl;
ListItemCollection listItems = list.GetItems(camlQuery);
cxt.Load(listItems);
cxt.ExecuteQuery();
foreach (ListItem listItem in listItems)
{
if (listItem.FileSystemObjectType == FileSystemObjectType.File)
{
fullfilePaths.Add(String.Format("{0}{1}", server, listItem["FileRef"]));
}
else if (listItem.FileSystemObjectType == FileSystemObjectType.Folder)
{
Console.WriteLine(String.Format("{0}{1}", server, listItem["FileRef"]));
fullfilePaths.Add(String.Format("{0}{1}", server, listItem["FileRef"]));
}
}
}
return fullfilePaths;
}
private static SharePointOnlineCredentials GetCreds(string username, string password)
{
SecureString securePassword = new SecureString();
foreach (char c in password.ToCharArray()) securePassword.AppendChar(c);
return new SharePointOnlineCredentials(username, securePassword);
}
In terms of the threshold limit, I have tried this on a folder with only 1 file and 1 folder in (in turn that folder has 1 file only), so if the limit is default 5000, I have no idea why I'd be getting this.
Finally found a solution that works, even if it is a bit sledgehammer!
Although the folders I was looking to retrieve the items for had far less than 5000 items, the issue was the list as a whole did exceed this threshold (In this case it was about 11,000 items).
I removed the FolderServerRelativeURL attribute and then used ListItemCollectionPosition to paginate/batch up the all the items in the list. Once all the items are in a collection it can be filtered with Linq for the relevant subfolder. (CAML Query - Going around the 5000 List Item Threshold)
If anyone has a way of being more targeted with the items, I'd love to see it.
Code:
public static IEnumerable<ListItem> GetSharepointFiles2(string sharePointsite, string libraryName, string username, string password, string subFolders)
{
Uri filename = new Uri(sharePointsite);
List<ListItem> items = new List<ListItem>();
using (ClientContext cxt = new ClientContext(filename))
{
cxt.Credentials = GetCreds(username, password);
Web web = cxt.Web;
cxt.Load(web, wb => wb.ServerRelativeUrl);
cxt.ExecuteQuery();
List list = web.Lists.GetByTitle(libraryName);
cxt.Load(list);
cxt.ExecuteQuery();
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = "<View Scope='Recursive'><RowLimit>5000</RowLimit></View>";
do
{
ListItemCollection listItems = list.GetItems(camlQuery);
cxt.Load(listItems);
cxt.ExecuteQuery();
items.AddRange(listItems);
camlQuery.ListItemCollectionPosition = listItems.ListItemCollectionPosition;
} while (camlQuery.ListItemCollectionPosition != null);
var filteritems = items.Where(tt => tt.FieldValues["FileRef"].ToString().StartsWith(web.ServerRelativeUrl + subFolders));
return filteritems;
}
}

Sharepoint - uploading files with column values can't load Taxonomy fields in target

I am trying to transfer files from one document library on one farm to another. Since both are accessible from same network, I thought of getting column values from source and directly add it into a item on destination. Also upload the file along with the item.
List list = ccSource.Web.Lists.GetByTitle("Source Library");
ccSource.ExecuteQuery(); // ccSource is initialized with source Site collection
CamlQuery query = new CamlQuery();
ListItemCollection itemCollection = list.GetItems(CamlQuery.CreateAllItemsQuery()); //Query can also be selective
ccSource.Load(list);
ccSource.Load(itemCollection);
ccSource.ExecuteQuery();
ccSource.Load(ccSource.Web);
string[] coloumnsList = System.IO.File.ReadAllLines(#"E:\Coloumns.txt");
foreach (ListItem item in itemCollection)
{
ClientContext ccTarget. = new ClientContext("http://TargetSC/sites/mysite");
ccTarget.Credentials = new NetworkCredential("username", "pass", "domain");
ccTarget.ExecuteQuery();
var targetList = ccTarget.Web.Lists.GetByTitle("TargetLibrary");
string diskFilePath = #"E:\downloadedFile.docx"; //I have skipped the download code
var fileInfo1 = new FileCreationInformation
{
Url = System.IO.Path.GetFileName(diskFilePath),
Content = System.IO.File.ReadAllBytes(diskFilePath),
Overwrite = true
};
var file = targetList.RootFolder.Files.Add(fileInfo1);
var itemTar = file.ListItemAllFields;
//update list values
foreach (var allFields in item.FieldValues)
{
if (allFields.Key == "FileLeafRef" || checkColoumn(coloumnsList,allFields.Key))
itemTar[allFields.Key] = allFields.Value;
}
itemTar.Update();
ccTarget.ExecuteQuery(); //Exception here
}
public static bool checkColoumn(string[] arr,string query)
{
bool flag = false;
for (int i = 0; i < arr.Length; i++)
{
if (arr[i].Equals(query))
{flag = true; break;}
}
return flag;
}
I am getting exception:
The given guid does not exist in the term storeon
ccTarget.exceuteQuery()

C# client object

I want to read a specific SharePoint list into a datatable. I am struggeling to read the Lookup Values.
Example:
Customer list, each customer is assigned to a team member. The Team members are a lookup of the Team member list.
I have the following questions:
1.) How can I get the Information which list is linked to this lookup field?
2.) How can read the field, gets the value or the index?
I added my function below, many thanks for helping a desperate novice in SharePoint...
Regards
Volker
public System.Data.DataTable ReadDatafromSPList(ClientContext clientContext, string ListName, string ViewName)
{
Web site = clientContext.Web;
List list = site.Lists.GetByTitle(ListName);
View view = list.Views.GetByTitle(ViewName);
ViewFieldCollection viewFields = view.ViewFields;
clientContext.Load(view);
clientContext.ExecuteQuery();
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = view.ViewQuery;
ListItemCollection ListColletion = list.GetItems(camlQuery);
clientContext.Load(list);
clientContext.Load(ListColletion);
clientContext.Load(viewFields);
clientContext.ExecuteQuery();
string[] headers = view.ViewFields.ToArray();
System.Data.DataTable dTable = new System.Data.DataTable();
foreach (string header in headers)
{
dTable.Columns.Add(header);
}
string str="";
foreach (ListItem item in ListColletion)
{
dTable.Rows.Add(dTable.NewRow());
foreach (string header in headers)
{
try
{
str = item[header].ToString();
if (str == "Microsoft.SharePoint.Client.FieldLookupValue")
{
//??????????????????
//??????????????????
}
dTable.Rows[dTable.Rows.Count - 1][header] = str;
}
catch
{
dTable.Rows[dTable.Rows.Count - 1][header] = "";
}
}
}
return dTable;
}
Do try this..
ClientContext context = new ClientContext(ServerText.Text);
List list = context.Web.Lists.GetByTitle("Tasks");
CamlQuery query = new CamlQuery();
query.ViewXml = "<View/>";
ListItemCollection items = list.GetItems(query);
context.Load(list);
context.Load(items);
context.ExecuteQuery();
DataTable table = new DataTable();
table.Columns.Add("Id");
table.Columns.Add("Title");
foreach (ListItem item in items)
table.Rows.Add(item.Id, item["Title"]);

Simple list items validation (prevent duplicates)

Hi currently I have code that get the value of of a list item and checks to see whether the value in this list (the value in a "Phone number" column) exists agains a value sugmitted by a HTML form. If the record to be entered into the list via this HTML form contains a Phone number that is already in the list, the record will not be added. This works well for the first item in the list, however when another item is added into the list with a different Phone number, the code does not seem to pick up the Phone number for the second record and so if a third record is entered with same Phone number as the second record the validation does not take place, the code keeps on looking at the first record. Here is a listing of my code:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(valueListURL))
{
using (SPWeb web = site.OpenWeb())
{
try
{
//--This is very important--
web.AllowUnsafeUpdates = true;
SPList list = web.Lists["Contact Requests"];
SPListItemCollection collsListItems = list.Items;
//Following lines of code added for validation
oreach (SPListItem objListItem in list.Items)
{
string valuePhonenumber = objListItem["Phone number"].ToString();
string valueEmailaddress = objListItem["Email address"].ToString();
SPListItem newItem = list.Items.Add();
if (TextBox3.Text != valuePhonenumber)
{
newItem["Contact name"] = TextBox1.Text;
TextBox1.Text = null;
newItem["Company"] = TextBox2.Text;
TextBox2.Text = null;
newItem["Phone number"] = TextBox3.Text;
this.TextBox3.Text = null;
newItem["Email address"] = TextBox4.Text;
TextBox4.Text = null;
newItem["Best time to call you"] = TextBox5.Text;
TextBox5.Text = null;
newItem["Enquiry subject"] = DropDownList1.SelectedItem;
this.DropDownList1.ClearSelection();
newItem["Enquiry details"] = TextBox6.Text;
this.TextBox6.Text = null;
if (RadioButton1.Checked)
newItem["Contact method"] = Label1.Text;
this.RadioButton1.Checked = false;
if (RadioButton2.Checked)
newItem["Contact method"] = Label2.Text;
this.RadioButton2.Checked = false;
newItem.Update();
}
//this.Response.Redirect(Request.RawUrl);
//Lines of code below used to insert or inject a javacript in order to close
//modeal dialog box at the press of the button
this.Page.Response.Clear();
this.Page.Response.Write("
<script type=text/javascript>window.frameElement.commonModalDialogClose(1, 1);</script>");
//this.Page.Response.Write("Submitted!"); //replacement for the above javascript
this.Page.Response.End();
}
}
catch (Exception doh)
{
DisplayError(doh);
}
}
}
});
I am thinking of using a foor loop to iterate throught the list items to check for exisiting Phone number records. I am think of putting the
if (TextBox3.Text != valuePhonenumber)
{
}
shown in the code above inside of a foor loop, but Im not sure on how to achieve this without breaking the code. Would be much appreciated if anyone could assist me with this!
Thanks in advance,
Update!!!
I am now using caml query to query the list for the required value in this case its the value entered on the HTML form into TextBox3.Text. The result of the qquery then gets stored in the object "listItemsCollection". I then use this perform a check so if the value in "TextBox3.text" is not equal to the value stored in "listItemsCollection" then the records get added to the list, if it is equal then the records does not get added. The code is listed below:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(valueListURL))
//using (SPSite site = new SPSite(webUrl))
{
using (SPWeb web = site.OpenWeb())
{
try
{
//added to resolve the issue with security validation on the page
//--This is very important--
web.AllowUnsafeUpdates = true;
SPList list = web.Lists["Contact Requests"]
SPQuery query = new SPQuery();
// try and find phone number we dont want to add in list
string camlquery = "<Where><Eq><FieldRef Name='Phone number'/>" + "<Value Type='Text'>"
+ TextBox3.Text + "</Value></Eq></Where>";
query.Query = camlquery;
SPListItemCollection listItemsCollection = list.GetItems(query);
if (TextBox3.Text != listItemsCollection.ToString()) // if it doesn't exist in list,
//we can add it records
{
SPListItem newItem = list.Items.Add();
// add code goes here
newItem["Contact name"] = TextBox1.Text;
TextBox1.Text = null;
newItem["Company"] = TextBox2.Text;
TextBox2.Text = null;
newItem["Phone number"] = TextBox3.Text;
this.TextBox3.Text = null;
newItem["Email address"] = TextBox4.Text;
TextBox4.Text = null;
newItem["Best time to call you"] = TextBox5.Text;
TextBox5.Text = null;
newItem["Enquiry subject"] = DropDownList1.SelectedItem;
this.DropDownList1.ClearSelection();
newItem["Enquiry details"] = TextBox6.Text;
this.TextBox6.Text = null;
if (RadioButton1.Checked)
newItem["Contact method"] = Label1.Text;
this.RadioButton1.Checked = false;
if (RadioButton2.Checked)
newItem["Contact method"] = Label2.Text;
this.RadioButton2.Checked = false;
newItem.Update();
}
//this.Response.Redirect(Request.RawUrl);
//Lines of code below used to insert or inject a javacript in order to close
//modeal dialog box at the press of the button
this.Page.Response.Clear();
this.Page.Response.Write("<script
type=text/javascript>window.frameElement.commonModalDialogClose(1, 1);</script>");
//this.Page.Response.Write("Submitted!"); //replacement for the above javascript
this.Page.Response.End();
}
catch (Exception doh)
{
DisplayError(doh);
}
}
}
});
I haven't done much with CAML before which is why I seem to be struggling whith something that should be so simple. Any sujestions to get this working will be hugely appreciated!
Many thanks in advance
You could achieve this using a CAML Query. You simply create a query where the phone number equals (or contains, depends on your requirements) the input from the HTML form. When you execute the query, a result set (SPListItemCollection) is returned. If this result set already contains an item, you know it's a duplicate and do not add a new item. Refer to this article if you haven't worked with CAML Queries yet:
http://sharepointmagazine.net/articles/writing-caml-queries-for-retrieving-list-items-from-a-sharepoint-list
I finally found what the problem was, after doing some reading apparently when dealing with CAML its seems better to provide the internal system name of the list column or field. In my case I was using 'Phone number' before which is why the whole thing was not working.
string camlquery = #"<Where>
<Eq>
<FieldRef Name='Phone_x0020_number'/>
<Value Type='Text'>" + TextBox3.Text + #"</Value>
</Eq>
</Where>";
query.Query = camlquery;
SPListItemCollection listItemsCollection = list.GetItems(query);
if (listItemsCollection.Count == 0) // if it doesn't exist in list, we can add it
{
}
But by simply providing the internal system name for the list column or field as shown above ('Phone_x0020_number'). The whole thing now works. After all this time breakingmy head, all that was required was the internal system name for the column.....
private bool TryGetItem(Guid key, string value, SPList list, out SPListItemCollection items)
{
SPQuery query = new SPQuery();
string #template = #"<Where>
<Eq>
<FieldRef Name='{1}'/>
<Value Type='Text'>{0}</Value>
</Eq>
</Where>";
query.Query = string.Format(#template, key.ToString("D"), value);
items = list.GetItems(query);
return items.Count > 0;
}

Categories

Resources