How to edit and read data in a SharePoint List - sharepoint

I want to query a SharePoint list and want to use the data to be displayed in a usercontrol that I have created.
Earlier I had the data coming from a database.
Now I need to modify it to work with a SharePoint list.
Can you please guide me.
Grace.

SPList list = null;
SPListItemCollection LIC = null;
SPListItem listItem = null;
using (SPSite mainSite = new SPSite("http://sitewhereyourlistis"))
{
using (SPWeb mainWeb = mainSite.OpenWeb())
{
list = mainWeb.Lists["ListNameHere"];
//**You will most likely want to limit your return to a single record so I have created the caml to do so with the List Item ID
String caml = String.Format("<Where><Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">{0}</Value></Eq></Where>", ListItemID);
SPQuery qry = new SPQuery();
qry.Query = caml;
LIC = list.GetItems(qry);
listItem = LIC[0];
//**Here is where you will fill your textboxes
txtTextBoxName.Text = listItem["ColumnNameHere"].toString();
//**The above statement likes to error out if the value is null so I like to use a custom Application Helper Function to prevent things like this.
//**My actual call to get the data would look like this.
txtTextBoxName.Text = EnsureTextValue(listItem, "ColumnNameHere");
// I added the Function Definition Below
}
}
public String EnsureTextValue(SPListItem item, String param)
{
String tmp = String.Empty;
try
{
tmp = item[param].ToString();
}
catch { "Run Debug Method or Whatever Here" }
return tmp;
}
I am not sure if I missed anything but this should get you close.
Hope it helps!

To get Distinct Values for the column Click Here
To edit the values in the list there is a nice post here

I have used this to Query the SharePoint List
using (SPWeb web = SPContext.Current.Site.RootWeb)
{
SPList mylist = web.Lists["listName"];
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name='columnName' /><Value Type='Text'>" + strXYZ+ "</Value></Eq></Where>";
SPListItemCollection items = mylist.GetItems(query);
tempDT = items.GetDataTable();
return tempDT;
}

Related

Unable to fetch item in SharePoint List (threshold > 5000 ) through CSOM

I am trying to create a Windows Form for populating the information from SharePoint List into Windows Form. However, when I am trying to fetch the item from the list, it throws me an error message
An unhandled exception of type 'Microsoft.SharePoint.Client.PropertyOrFieldNotInitializedException' occurred in Microsoft.SharePoint.Client.dll
Additional information: The property or field has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested."
Here is the code for the same.
private void btn_populatecontainer_Click(object sender, EventArgs e)
{
var authManager = new AuthenticationManager();
ClientContext overviewlistClientcontext = authManager.GetWebLoginClientContext("Tenant URL");
var tenant = new Tenant(overviewlistClientcontext);
var siteProperties = tenant.GetSiteByUrl("SiteCollectionURL");
Web web = siteProperties.RootWeb;
List olist = web.Lists.GetByTitle("SiteOverviewList");
overviewlistClientcontext.Load(siteProperties);
overviewlistClientcontext.ExecuteQuery();
ListItemCollectionPosition position = null;
var page = 1;
do
{
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = #"<View Scope='Recursive'><RowLimit>4000</RowLimit><Query><Where><Eq><FieldRef Name='Site URL'/><Value Type='Text'>" + txtSite.Text + "</Value></Eq></Where></Query></View>";
camlQuery.ListItemCollectionPosition = position;
ListItemCollection listItems = olist.GetItems(camlQuery);
overviewlistClientcontext.Load(listItems);
overviewlistClientcontext.ExecuteQuery();
position = listItems.ListItemCollectionPosition;
DataTable dataTable = new DataTable();
DataRow dr;
DataColumn dc = new DataColumn("Site Owner");
dc.DataType = Type.GetType("System.String");
dataTable.Columns.Add(dc);
foreach (var listItem in listItems)
{
dr = dataTable.NewRow();
dr["Site Owner"] = listItem["Site Owner"];
dataTable.Rows.Add(dr);
}
OverViewListGrid.DataSource = dataTable;
OverViewListGrid.DataBindings
page++;*/
}
while (position != null);
}
}
}
I have debugged the code and it fails when it tries to execute query after fetching from Caml Query.
When CamlQuery gets executed, it doesn't work at all.
However, for the testing purpose, I have tried to fetch other columns and the code works if I try to fetch Title/Id Column directly using inbuilt functions (i.e. GetItembyID).
But even the second steps won't work if i use another column from the same list.
Can anyone help me with this?
To filter list items from list which over threshold, need use indexed column.
The Site URL need to be indexed column.
<Query><Where><Eq><FieldRef Name='Site URL'/><Value Type='Text'>" + txtSite.Text + "</Value></Eq></Where></Query>
Otherwise, you need get all items from SharePoint by pagination.
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = #"<View Scope='Recursive'><RowLimit>4000</RowLimit><Query></Query></View>";
Then, filter by Linq.
How I can filter a dataTable with Linq to datatable?
the exception says that You are trying to get value of a column that has not been initialized in the context. In order to get it You need to load it to the client context together with the list item collection. The simplest way to get all fields is to use 'FieldValuesAsText'. For Your code example the updated code would look like
.....
overviewlistClientcontext.Load(listItems, includes => includes.Include(i => i.FieldValuesAsText));
overviewlistClientcontext.ExecuteQuery();
position = listItems.ListItemCollectionPosition;
DataTable dataTable = new DataTable();
DataRow dr;
DataColumn dc = new DataColumn("Site Owner");
dc.DataType = Type.GetType("System.String");
dataTable.Columns.Add(dc);
foreach (var listItem in listItems)
{
dr = dataTable.NewRow();
dr["Site Owner"] = listItem.FieldValuesAsText["Site Owner"];
dataTable.Rows.Add(dr);
}
.....
Also please be aware that You should use internal name (not display name) of column to get the field value. So I suspect that the internal name for You column 'Site Owner' would be 'Site_x0020_Owner' so You should take it like:
dr["Site Owner"] = listItem.FieldValuesAsText["Site_x0020_Owner"];
In order to check what is the internal name of Your column, the easiest way is to enter edit page of Your column and the internal name will be part of the URL as one of the GET parameters

Multi-Select fields on a Sharepoint list using OWSSVR.dll

I am in the process of creating a massive SSIS project to move the data from a series of Sharepoint Lists to a new Dynamics CRM Implementation (On-line). The SSIS package uses an OData Source to pull the data from the lists.
There are two columns on my list that do not show up on the OData call. These two columns have Multi-Select or Multi-Lookup values. REST services do not support multi-select choice fields. (Found on another thread: The methods you are attempting only work with choice columns that are NOT multi-select. Unfortunately, multi-select choice columns are not supported by the REST interface. Same holds true for SharePoint 2013 apparently.)
Therefore, I need to try to access the data in these columns on the SharePoint List using the OWSSVR.dll. The list I am having issues with gives me a "This page can’t be displayed" or a "This site can’t be reached" depending on the browser I use.
I verified the List ID by grabbing It from the list settings. Since it didn't work, I went to another SharePoint List I already migrated to verify the URL format. The other list works and brings back the data in XML format.
I am wondering if the OWSSVR.dll has the same restriction on Multi-select values. Any ideas or suggestions?
Psuedo URLS (restricted access site):
Works: http://dummy.sharepointSite.Com/cases/_vti_bin/owssvr.dll?Cmd=Display&List={b703d405-48c8-4211-9137-e1b50bdb0330}&XMLDATA=TRUE
Broken: http://dummy.sharepointSite.Com/cases/_vti_bin/owssvr.dll?Cmd=Display&List={8e148584-b5be-48f5-9343-85d23a7731cc}&XMLDATA=TRUE
I figured out a way to do this without using OWSSVR. I have to set up the User Context to the SharePoint site then retrieve the list of items.
Methods:
public static ClientContext SetupSPContext(string documentLibrarySiteURL,
string userName, string password, string domain = "")
{
ClientContext clientContext = new ClientContext(documentLibrarySiteURL);
SecureString pwString = new SecureString();
foreach (char c in password.ToCharArray()) { pwString.AppendChar(c); }
if (!String.IsNullOrWhiteSpace(domain))
clientContext.Credentials = new NetworkCredential(userName, pwString, domain);
else
clientContext.Credentials = new SharePointOnlineCredentials(userName, pwString);
Web web = clientContext.Web;
clientContext.Load(web);
clientContext.ExecuteQuery();
return clientContext;
}
public static ListItemCollection GetListItems(ClientContext context, string listName)
{
ListCollection listCollection = context.Web.Lists;
List targetList = context.Web.Lists.GetByTitle(listName);
CamlQuery query = new CamlQuery();
query.ViewXml = "<Query><OrderBy><FieldRef Name='fieldName' /></OrderBy></Query>";
ListItemCollection collListItem = targetList.GetItems(query);
context.Load(collListItem);
context.ExecuteQuery();
if (collListItem.Count == 0)
{
return null;
}
else
{
return collListItem;
}
}
Code in SSIS Script Component:
//In the PreExecute method:
// Variables were defined for the class and not in the preExecute Method
ClientContext spContext = SetupSPContext(Variables.spLocation, Variables.spUserName,
Variables.spPassword, Variables.spDomain);
ListItemCollection listItems = GetListItems(spContext, "List Name");
//Inside the Individual loop inside SSIS (Input0_ProcessInputRow):
ListItem listItem = GetListItem(listItems, fieldValue);
//Multiple Lookup Code
var values = (FieldLookupValue[])listItem["fieldName"];
var finalValue = "FieldName values: ";
if (values.Length > 0)
{
foreach (var value in values)
{
finalValue = value.LookupValue + "; ";
}
}
//Multiple Select
if (listItem["fieldName2"] != null)
{
var valuesTwo = (string[])listItem["fieldName2"];
string combinedValues = "fieldName2 Values: ";
foreach (var value in valuesTwo)
{
combinedValues += value + "; ";
}
}

Get Item based on index from Sharepoint CAML Query to SPListItemCollection

I am trying to query list items using caml (first time doing this) and sort the items based on modified date so I can get access to most recent documents. However when trying to get the SPListItem based on the ID I am failing.
Code:
SPQuery query = new SPQuery();
String camlquery = "<OrderBy><FieldRef Name='Modified' Ascending='False' /></OrderBy>";
query.ViewAttributes = "Scope = 'Recursive'";
query.ViewFields = "<FieldRef Name='Modified' /><FieldRef Name='Title' /><FieldRef Name='Name' />";
query.Query = camlquery;
query.IncludeMandatoryColumns = true;
SPListItemCollection col = list.GetItems(query);
//failing here... I think
SPListItem item = col.GetItemById(0);
Is there a way to get an SPListItem based on its index from within the SPListItemCollection?
I have tried
SPListItem item = col[0];
Also with no luck.
Here is the error I am getting:
Value does not fall within the expected range.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentException: Value does not fall within the expected range.
If you want to get a SPListItem using Id then you do not need to go for caml, try this,
SPSite oSite = new SPSite("http:/MyTestSite/");
SPWeb oWeb = oSite.OpenWeb();
SPList oList = oWeb.Lists["MyCustomList"];
SPListItem oListItem = oList.Items.GetItemById(1);
But If you insist on getting it by using caml, make sure you include Id in your ViewFields caml query.
And get the items using Id as :
foreach (ListItem item in col)
{
if(item["Id"] == 1) //Only an example
{
var itemFromId = item;
}
}
Also to note, The value of the ID property is not the same as the index of the item in the collection of list items. This property contains the item's 1-based integer ID, which is one greater than the ID of the item that was previously added. If the item is deleted, its ID is not reused.[MoreInfo]
The issue was with the collection that I was returning. I had to make sure there were results prior to using the item:
if (col.Count > 0)
{
SPListItem item = col[0];
}
Silly mistake.

get guid of a listitem

I have text file with List Name and item name. I need to get item guid by it's name. how? (not using foreach splistitem item in splist cause the text file is large and the loop is going to take a toll)
You may have enough information to use the SPWeb function GetListItem, otherwise you will need to try SPWeb.SearchListItems. Neither of which is going to be all the fast either.
The web services have a decent search function that I have used such as:
public static string GetPageId(string listName, string webPath, string pageTitle)
{
string pageId = "";
IntranetLists.Lists lists = new IntranetLists.Lists();
lists.UseDefaultCredentials = true;
lists.Url = webPath + "/_vti_bin/lists.asmx";
XmlDocument doc = new XmlDocument();
doc.LoadXml("<Document><Query><Where><Contains><FieldRef Name=\"Title\" /><Value Type=\"Text\">" + pageTitle + "</Value></Contains></Where></Query><ViewFields /><QueryOptions /></Document>");
XmlNode listQuery = doc.SelectSingleNode("//Query");
XmlNode listViewFields = doc.SelectSingleNode("//ViewFields");
XmlNode listQueryOptions = doc.SelectSingleNode("//QueryOptions");
Guid g = GetWebID(webPath);
XmlNode items = lists.GetListItems(listName, string.Empty, listQuery, listViewFields, string.Empty, listQueryOptions, g.ToString());
foreach (XmlNode listItem in SPCollection.XpathQuery(items, "//sp:listitems/rs:data/z:row"))
{
XmlAttribute id = listItem.Attributes["ows_Id"];
if (id != null)
{
pageId = id.Value;
}
}
return pageId;
}
public static XmlNodeList XpathQuery(XmlNode xmlToQuery, string xPathQuery)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlToQuery.OuterXml);
XmlNamespaceManager mg = new XmlNamespaceManager(doc.NameTable);
mg.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/soap/");
mg.AddNamespace("z", "#RowsetSchema");
mg.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");
mg.AddNamespace("y", "http://schemas.microsoft.com/sharepoint/soap/ois");
mg.AddNamespace("w", "http://schemas.microsoft.com/WebPart/v2");
mg.AddNamespace("d", "http://schemas.microsoft.com/sharepoint/soap/directory");
return doc.SelectNodes(xPathQuery, mg);
}
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsitedataquery.aspx or CamlQuery
SPListItemCollection items = web.Lists.GetItems(new SPQuery() { Query = "YOUR QUERY" });
Go to the list settings page. Right click on "Title, description and navigation" and copy the URL. Paste that into notepad and copy everything after "List=" in the string. That's your URL Encoded GUID for the list. All you need to do is decode it here http://www.albionresearch.com/misc/urlencode.php
source: http://weblogs.asp.net/jimjackson/archive/2008/02/11/get-a-sharepoint-list-guid-from-the-browser.aspx
this is for manually getting each GUID of a certain list.

Getting all the webpages of a SPWeb and subwebs that have a field with a value in Sharepoint?

I have a website in Sharepoint 2007. I want to make a query where the field "home" of the webpages is equal to 1 in one specific SPWeb and (this is the important part) its sub-SPwebs.
I can make this work with the site in question and not with the subsites. That is to say: It is not recursive but I indicate it in the "webs scope='recursive'" clause.
I include also the List I want to use, that is to say, the pages (not documents, master pages or whatever) this is whay i look for the "850" basetemplate (the one for pages).
The code I am using is this (i have tried with other methods with the same query and the result is the same):
string campo="home";
SPSiteDataQuery qry = new SPSiteDataQuery();
qry.Query = "<Where><Eq><FieldRef Name='";
qry.Query += campo + "'/><Value
Type='Boolean'>1</Value></Eq>";
qry.Query += "</Where><OrderBy><FieldRef
Name='Modified' Ascending='false'> />";
qry.Webs = "<Webs Scope='Recursive'/>";
qry.ViewFields = "<FieldRef Name='Title'/><FieldRef
Name='Modified'/>";
//this gives me system privileges
using (SPSite site = new SPSite(CurrentSite.ID,
GetSystemToken(CurrentSite)))
{
using (SPWeb web = site.OpenWeb("/News/"))
{
StringBuilder sb = new StringBuilder();
sb.Append("<Lists>");
foreach (SPList list in web.Lists)
{
if (list.BaseTemplate.ToString() ==
"850")
{
sb.Append("<List ID=\"" +
list.ID.ToString() + "\"/>");
}
}
sb.Append("</Lists>");
qry.Lists = sb.ToString();
dt = web.GetSiteData(qry);
..................
So, the only solution I found was to make a loop after the precedent code through the Webs but i don't think this is a very optimized way:
foreach (SPWeb w2 in web.Webs)
{
sb = new StringBuilder();
sb.Append("<Lists>");
foreach (SPList list in w2.Lists)
{
if (list.BaseTemplate.ToString()
== "850")
{
sb.Append("<List ID=\""
+ list.ID.ToString() + "\"/>");
}
}
sb.Append("</Lists>");
qry.Lists = sb.ToString();
DataTable dttmp = w2.GetSiteData(qry);
if (dttmp != null
&& dttmp.Rows.Count > 0)
{
dt.Merge(dttmp);
}
w2.Dispose();
}
Finally I did the following, i don't know what has worked finally, i have changed the way I ask the Lists and i have included RowLimit:
DataTable dt = null;
DataView dv = null;
SPSiteDataQuery qry = new SPSiteDataQuery();
qry.Query = "<Where><Eq><FieldRef Name='";
qry.Query += campo + "'/><Value Type='Boolean'>1</Value></Eq>";
qry.Query += "</Where><OrderBy><FieldRef Name='Modified' Ascending='false' /></OrderBy>";
qry.Webs = "<Webs Scope='Recursive'/>";
qry.Lists = "<Lists ServerTemplate='850' Hidden='FALSE' MaxListsLimit='50'/>";
qry.RowLimit = 3;
qry.ViewFields = "<FieldRef Name='Title'/><FieldRef Name='Modified'/><FieldRef Name='FileRef'/>";
using (SPSite site = new SPSite(CurrentSite.ID, GetSystemToken(CurrentSite)))
{
using (SPWeb web = site.OpenWeb(webUrl))
{
dt = web.GetSiteData(qry);
dv = dt.DefaultView;
}
}
return dv;
You talk about setting the webs scope to recursive, but in your (ill-formatted) example code you leave the webs property blank, meaning the site data query will only search through the specified web.
This specific (omitted) detail of your code is very important, because making even the slightest spelling mistake in the innerXML specification will silently revert the behaviour back to the default, meaning only the current web will be searched. A typical pitfall would be getting the capitalization wrong in either Webs or Scope.
For the record, the correct way of specifying this is
qry.Webs = "<Webs Scope='Recursive' />";
As a quick check, you can try setting the scope to SiteCollection, see if that works.
[Edit] Agreed, now your Webs property shows up it seems fine :-). Have you tried setting the Nullable='TRUE' attribute in the fieldref of the Campo field? If the field isn't present (or corrupted or whatever) in any of the subsites, that might help. [/Edit]

Resources