Introduction
Working with MOSS 2007 is simple and easy since you can create your own lists and manage them through SharePoint website settings. But when we start building a website under SharePoint, we need to manage and customize these lists from code. I created a small website using Microsoft.SharePoint.dll, to manage SharePoint lists.
Background
My website starts by accessing a SharePoint website created locally on my computer. The first step is to access the SPSite
and get the current SharePoint Website (SPWeb
). After this, we can start with reading all the website lists and start managing them through SPList
, and each list has a list of SPListItem
s.
Using the Code
Using the Microsoft.SharePoint
namespace, we start by getting the current SPWeb
. For the SPSite
, we need to specify the URL for the SharePoint website we are using:
SPSite site = new SPSite("http://localhost:48/");
SPWeb myWeb = site.OpenWeb();
myWeb.AllowUnsafeUpdates = true;
dgvLists.DataSource = myWeb.Lists;
dgvLists.DataBind();
myWeb.Close();
site.Close();
AllUnssite.Close();
AllUnsafeUpdates
is set to true
since we are modifying the website lists from outside SharePoint.
As shown in the picture above, we will get all the lists built in, or custom lists available in the current website. Now we can manage any list we need by clicking on the Edit button, or we can add a new list also from this page.
To add a new SPList
, we can use the following function:
Guid guid = Guid.Empty;
SPListTemplateType type = (SPListTemplateType)int.Parse(ddlType.SelectedValue);
guid = myWeb.Lists.Add(txtListName.Text, txtDescription.Text, type);
Every list in SharePoint has its unique identifier; this function returns this as a GUID that can be used for other purposes. Every list has its title, description, and SPListTemplateType
:
Now to edit an existing list, we have to first check the list of available fields in this list and determine which fields are read only, required, editable... To get the list information, we only need to know its title or list name using the following function:
SPList list = myWeb.Lists[txtListName.Text];
After we get the SPList
, we can loop over the list's Fields
using the SPField
list, and create a dummy table that contains the list of items that can be modified by the user (not read only fields).
if (list != null)
{
dgvFields.DataSource = list.Fields;
dgvFields.DataBind();
DataTable dt = new DataTable();
foreach (SPField field in list.Fields)
{
if (field.Title == "Property Bag")
continue;
if (!field.ReadOnlyField || field.Title == "ID")
{
DataColumn col = new DataColumn();
col.ColumnName = field.Title;
col.ExtendedProperties.Add("Type", field.TypeAsString);
col.ExtendedProperties.Add("Required", field.Required);
if (!dt.Columns.Contains(col.ColumnName))
dt.Columns.Add(col);
}
}
foreach (SPListItem item in list.Items)
{
DataRow row = dt.NewRow();
foreach (SPField field in item.Fields)
{
if (field.Title == "Property Bag")
continue;
if (!field.ReadOnlyField || field.Title == "ID")
{
row[field.Title] = item[field.Title];
}
}
dt.Rows.Add(row);
}
Session["CurrentTable"] = dt;
dgv.DataSource = dt;
dgv.DataBind();
}
In this step, we need to fill up the two grids in the page: the first one contains the list of SPField
s in the SPList
we are editing, and the second one contains a custom DataTable
built according to the selected fields that are not ReadOnlyField
. Or, we can use the default generated DataTable
:
dgv.DataSource = list.Items.GetDataTable();
dgv.DataBind();
As shown in the figure above, you can see the two grids now. The second one includes only the editable data in every SPList
.
We can also add new fields to this list:
if (list != null)
{
int type = 0;
int.TryParse(ddlFieldTypes.SelectedValue, out type);
list.Fields.Add(txtField.Text, (SPFieldType)type, chkRequired.Checked);
list.Update();
}
For every newly added field, we need to specify the field name, SPFieldType
, and whether it is required or not. list.Update()
is used to add the modification to the SharePoint database. SPFieldType
is variable, it can be a Number
, Text
, another List
...
Now, in the second grid, if we click on Edit or Add, then we can modify the exiting data of this SPListItem
:
As you can see, the fields are automatically generated depending on the type of each field; text is replaced with a textbox, boolean is replaced by Yes/No radiobuttons, and unknown types or readonly fields are replaced by labels.
protected void dgv_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Modify")
{
int index = Convert.ToInt32(e.CommandArgument);
DataTable dt = (DataTable)Session["CurrentTable"];
DataRow row = dt.Rows[index];
List<SpecificItem> items = new List<SpecificItem>();
txtId.Value = row["ID"].ToString();
foreach (DataColumn col in dt.Columns)
{
SpecificItem item = new SpecificItem();
item.ID = int.Parse(row["ID"].ToString());
item.ItemDisplay = col.ColumnName;
item.ItemType = col.ExtendedProperties["Type"].ToString();
item.ItemValue = row[col.ColumnName];
items.Add(item);
}
Session["CurrentRow"] = items;
rptItems.DataSource = items;
rptItems.DataBind();
listItems.Visible = true;
}
else if (e.CommandName == "Remove")
{
int index = Convert.ToInt32(e.CommandArgument);
DataTable dt = (DataTable)Session["CurrentTable"];
DataRow row = dt.Rows[index];
int id = 0;
int.TryParse(row["ID"].ToString(), out id);
list = myWeb.Lists[txtListName.Text];
if (list != null)
{
list.Items.DeleteItemById(id);
FillGrids();
}
}
}
SpecificItem
is a class created to access a custom list that will be given to the Repeater
in order to allow the modifications of the SPListItem
easily. This class includes:
public class SpecificItem
{
public int ID
{
get;
set;
}
public string ItemType
{
get;
set;
}
public string ItemDisplay
{
get;
set;
}
public object ItemValue
{
get;
set;
}
}
Now the Repeater
will have a data source that includes a list of SpecificItem
s. For each SpecificItem
, we can check the type and add the suitable control to allow the editing of the SPListItem
.
The backward step is used upon saving. We will check the SpecificItem
given to the Repeater
and match the types with the SPListItem
and then save the SPListItem
.
list = myWeb.Lists[txtListName.Text];
int id = 0;
int.TryParse(txtId.Value, out id);
List<SpecificItem> items = new List<SpecificItem>();
SPListItem item = null;
if (id > 0)
{
item = list.Items.GetItemById(id);
items = (List<SpecificItem>)Session["CurrentRow"];
}
else
{
item = list.Items.Add();
DataTable dt = (DataTable)Session["CurrentTable"];
foreach (DataColumn col in dt.Columns)
{
SpecificItem i = new SpecificItem();
i.ItemDisplay = col.ColumnName;
i.ItemType = col.ExtendedProperties["Type"].ToString();
items.Add(i);
}
}
foreach (SpecificItem i in items)
{
foreach (string key in Request.Form.AllKeys)
{
if (key.IndexOf("txt" + i.ItemType + "_" +
i.ID + "_" + i.ItemDisplay.Replace(" ", "")) >= 0)
{
if (key.IndexOf("DateTime") >= 0)
{
DateTime date = new DateTime();
DateTime.TryParse(Request.Form[key], out date);
if (date != DateTime.MinValue)
item[i.ItemDisplay] = date;
}
else
item[i.ItemDisplay] = Request.Form[key].ToString();
break;
}
if (key.IndexOf("chk" + "_" + i.ID + "_" +
i.ItemDisplay.Replace(" ", "")) >= 0)
{
item[i.ItemDisplay] = Request.Form[key] == "yes";
break;
}
if (key.IndexOf("txt" + i.ItemType + "_" + i.ID + "_" +
i.ItemDisplay.Replace(" ", "")) >= 0 &&
(key.IndexOf("Integer") > 0 || key.IndexOf("Number") > 0))
{
if (key.IndexOf("Integer") >= 0)
{
int val = 0;
int.TryParse(Request.Form[key].ToString(), out val);
item[i.ItemDisplay] = val;
}
else
{
double d = 0;
double.TryParse(Request.Form[key].ToString(), out d);
item[i.ItemDisplay] = d;
}
break;
}
}
}
item.SystemUpdate();
The SPListItem
item is an array of fields. To modify every field, we need to get the field title and place its value. item.SystemUpdate()
will save the list item into the database.
We can also delete the SPListItem
from the list after we get the SPListItem
ID:
list.Items.DeleteItemById(id);
In this way, we have viewed, edited, deleted, fully managed any SPList
without accessing the SharePoint website.
Points of Interest
For more details about the Microsoft.SharePoint
namespace, you can check the following link: Microsoft.SharePoint Namespace.