Improving SharePoint's SPListItemCollection GetDataTable(), let's get all the fields I need

Wednesday, 20 May 2009 10:34 by myro

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.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:   ,
Categories:   SharePoint 2007
Actions:   Bookmark and Share | Permalink | Comments (4) | Comment RSSRSS comment feed

Serialize and Deserialize objects into files using the System.Xml.Serialization in C# .NET

Tuesday, 19 May 2009 10:33 by myro

Serialization in C# and in .NET is really simple if just need to convert simple objects and collections in XML format. This article will show you the basic steps to serialize and deserialize objects into a xml file. Keep in mind that are different ways to accomplish this task, and you are always allowed to create you own serialization pattern implementing the ISerializable interface into your objects and collection. This time i will only cover the simple way by creating a colloection of my object that i want to serialize, a static manager (to simplify the serialization / deserialization process) and a simple console application to display you the result. 
Imagine you need to save or load a specific configuration file for your application at runtime… would it be nice to create a simple XML file which allows to edit it?  Here’s the deal:

First of all you need to create an object that you need to serialize:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Collections;

namespace SampleSerailizer
{
    [Serializable]
    public class Configuration
    {
        public Configuration()
        {

        }

        [XmlAttribute("Name")]
        public string Name { get; set; }

        [XmlAttribute("ID")]
        public int ID { get; set; }

        [XmlElement("Values")]
        public string[] Values { get; set; }

    }
}

You can see how is easy to determine which properties needs to be serialized: just add the proper decoration attribute to your properties. You can use theXmlIgnore decoration

[XmlIgnore]

if you want to skip this process for a specific property.

Now we need a class that will care to do this job. I have created a static class named ConfigurationManager and created 2 static methods that allows me to save or to load my objects:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace SampleSerailizer
{
     public static class ConfigurationManager
    {
         public static List<Configuration> LoadConfiguration(string path)
         {
             List<Configuration> toReturn;
             XmlSerializer serializer = new XmlSerializer(typeof(List<Configuration>));
             TextReader reader = new StreamReader(path);
             toReturn = (List<Configuration>)serializer.Deserialize(reader);
             reader.Close();
             return toReturn;
         }

         public static void SaveConfiguration(List<Configuration> configuration, string path)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<Configuration>));
            TextWriter writer = new StreamWriter(path);
            serializer.Serialize(writer, configuration);
            writer.Close();
        }
    }
}

You are done! Let’s create some sample data and try to serialize it into a XML format.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace SampleSerailizer
{
    class Program
    {
        static void Main(string[] args)
        {
            // lets add some sample configurations
            List<Configuration> list = new List<Configuration>();
            list.Add(new Configuration() {
                ID = 1 ,
                Name = "Application Configuration",
                Values = new string[] { "sample data 1", "sample data 2" }
            });

            list.Add(new Configuration()
            {
                ID = 2,
                Name = "More Configurations",
                Values = new string[] { "sample data 3", "sample data 4" }
            });

            //save the configuration to a xml file
            ConfigurationManager.SaveConfiguration(list, @"sample configuration.xml");

            //load the configuration from a xml file
            List<Configuration> loadedConfiguration =
           ConfigurationManager.LoadConfiguration(@"sample configuration.xml");

            // display the configuration collection
            foreach (var conf in loadedConfiguration)
            {
                Console.WriteLine(String.Concat(conf.ID, ". - ", conf.Name));
                foreach (var str in conf.Values)
                {
                    Console.WriteLine(String.Concat("--- ", str));
                }
                Console.WriteLine();
            }

            Console.ReadLine();

        }
    }
}

The output displayed in the console compared to the sample configuration.xml shows that it works..

Console output:
ConsoleXML sample configuration.xml:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Configuration Name="Application Configuration" ID="1">
    <Values>sample data 1</Values>
    <Values>sample data 2</Values>
  </Configuration>
  <Configuration Name="More Configurations" ID="2">
    <Values>sample data 3</Values>
    <Values>sample data 4</Values>
  </Configuration>
</ArrayOfConfiguration>

This snipped can be used for a quickly reference to this approach. For a deeper explanation, consider visiting the msdn.

Download the source code: SampleSerailizer.rar (23.84 kb)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:   ,
Categories:   .NET
Actions:   Bookmark and Share | Permalink | Comments (0) | Comment RSSRSS comment feed

Add SharePoint Web Part into DispForm, NewForm and EditForm using your browser

Friday, 15 May 2009 14:43 by myro

If you are using SharePoint Designer to edit your pages layout, you should probably know that you can customize the DispForm.aspx, NewForm.aspx and the EditForm.aspx easly. You are able to insert text, modify the page layout and insert SharePoint 2007 Web Parts. But what happens if you don't have installed SharePoint Designer? You are missing the Site Action button and the Modify Page link button.... To avoid this problem add this querystring parameter in your form url:

ToolPaneView=2  

A example to this solution is and url builded in this way:
http://YourSite/Lists/YourList/NewForm.aspx?ToolPaneView=2

Now you cand edit your page by adding any Web Part that is installed in your Site Collection.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:  
Categories:   SharePoint 2007
Actions:   Bookmark and Share | Permalink | Comments (1) | Comment RSSRSS comment feed