During SharePoint's development some situations can be easly solved treating SPListItemCollection as a simple DataTable, where each fields rappresents a column and the SpListItem rappresents a single row. SharePoint's SpListItemCollection provides a method called GetDataTable() which returns a DataTable type that doesn't contains all the item's fields. What you get are only the following DataColumns:
- URL,System.String
- Comments,System.String
- ID,System.Int32
- ContentType,System.String
- Modified,System.DateTime
- Created,System.DateTime
- Author,System.String
- Editor,System.String
- _UIVersionString,System.String
- Attachments,System.String
- DocIcon,System.String
- URLwMenu,System.String
- URLNoMenu,System.String
So, what happens if you want to see all those hidden fields that SharePoint hides? And what about if you need to get the data stored in an added SharePoint Field? Can I get the data using SharePoint's Views filtering?
To solve this particular issue I made an method that returns a DataTable, with all the datas that you should need and takes as input a SharePoint SpList's url and a boolean value that indicates the View should be considered. This are the features offered:
-
You can always get this senstive data, without using SharePoint Views:
- Author
- Editor
- Created
- Modified
-
You can always access to this fields without caring about the current view:
- Title
- Item's Disp Form absolute url
-
You can decide if you want use a SharePoint's View name or just get all the fields, including those that are hidden
Improvement's should be considered, because this method have solved a personal particular situation. I have test it on differents SharePoint SpList's Templates and it works well, but if you find a bug, don't blame me... fix it and post it so i can update thise page.
Here's the code snippet:
private DataTable GetDataTable(string listUrl, bool useFilterView)
{
DataTable dt;
if (String.IsNullOrEmpty(listUrl))
return null;
string ITEM_LINK_URL = "GOTO_ITEM_URL";
string ITEM_ENCODED_ABS_URL = "EncodedAbsUrl";
using (SPSite site = new SPSite(listUrl))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.GetListFromUrl(listUrl);
dt = new DataTable();
SPListItemCollection itemCollection;
StringCollection fieldsNameCollection;
if (useFilterView)
{
SPView view = web.GetViewFromUrl(listUrl);
SPQuery query = new SPQuery(view);
query.ViewFields = EnsureBasicFields(query.ViewFields);
itemCollection = list.GetItems(query);
}
else
{
itemCollection = list.Items;
}
fieldsNameCollection = itemCollection.QueryFieldNames;
for (int i = 0; i < fieldsNameCollection.Count; i++)
{
if (fieldsNameCollection[i].StartsWith("ows_"))
fieldsNameCollection[i] = fieldsNameCollection[i].Remove(0, 4);
dt.Columns.Add(new DataColumn(fieldsNameCollection[i]));
}
dt.Columns.Add(new DataColumn(ITEM_LINK_URL));
foreach (SPListItem item in itemCollection)
{
DataRow dr = dt.NewRow();
for (int i = 0; i < fieldsNameCollection.Count; i++)
{
SPField field = list.Fields.GetFieldByInternalName(fieldsNameCollection[i]);
if (field == null)
throw new Exception();
if (field is SPFieldLookup)
{
SPFieldLookup lf = (SPFieldLookup)field;
dr[field.InternalName] = lf.GetFieldValueAsText(item[field.InternalName]);
}
else if (field is SPFieldUrl)
{
SPFieldUrl lf = (SPFieldUrl)field;
dr[field.InternalName] = lf.GetFieldValueAsHtml(item[field.InternalName]);
}
else dr[field.InternalName] = item[field.InternalName];
}
if (list.BaseTemplate == SPListTemplateType.DocumentLibrary ||
list.BaseTemplate == SPListTemplateType.PictureLibrary)
{
dr[ITEM_LINK_URL] = item[ITEM_ENCODED_ABS_URL];
}
else
{
dr[ITEM_LINK_URL] = String.Concat(item.Web.Url, "/",
item.ParentList.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url,
"?id=", item.ID.ToString());
}
dt.Rows.Add(dr);
}
}
}
return dt;
}
private static string EnsureBasicFields(string viewFields)
{
string TITLE = "Title";
string AUTHOR = "Author";
string EDITOR = "Editor";
string CREATED = "Created";
string MODIFIED = "Modified";
string ITEM_ENCODED_ABS_URL = "EncodedAbsUrl";
string[] BASIC_FIELDS = new string[] { TITLE,
AUTHOR, EDITOR, CREATED, MODIFIED, ITEM_ENCODED_ABS_URL };
foreach (string str in BASIC_FIELDS)
{
if (!viewFields.Contains(String.Format("<FieldRef Name=\"{0}\" />", str)))
viewFields = String.Concat(viewFields,
String.Format("<FieldRef Name=\"{0}\" />", str));
}
return viewFields;
}
If you run this code in debug and set a breakpoint on the last line when viewFields is returned you can see that all the fields are present in the DataTable and a GOTO_ITEM_URL column contains an abolsute url to the item.
Remember that all those variables named in uppercase should be defined in your code as costants as class fields.