Wednesday, February 18, 2009

Reading SharePoint Lists into an ADO.Net DataTable, Updated

I've been integrating processes with SharePoint lists for some time now. I made a post back in September '08 about how to pull a SharePoint list into an ADO.NET DataTable.

A very kind reader contributed a much appreciated simplified solution. It actually worked for general cases, but didn't solve a fundamental problem (one of the reasons I posted my version of the code to begin with): What if you have a column with odd characters in the name, like "EntityA.Property1"?

Unfortunately, ADO.NET imports columns with certain character encodings as DBNull. I suspect this might be a bug, but the example below shows a very simple WPF form that uses the basic technique with a slight variation to work around the issue:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using data = System.Data;
using xml = System.Xml;
namespace WindowsApplication1
{
///
/// Interaction logic for Window1.xaml
///

public partial class Window1 : System.Windows.Window
{


public Window1()
{
InitializeComponent();
}


public void OnLoaded(object sender, RoutedEventArgs args)
{
SharePointLists.
Lists listsService = new WindowsApplication1.SharePointLists.Lists();
listsService.Url =
"http://spsite/_vti_bin/lists.asmx";
listsService.Proxy =
null;
listsService.UseDefaultCredentials =
true;
xml.
XmlNode listData =
listsService.GetListItems(
"Test List",
default(string),
null,
null,
default(string),
null,
default(string));

//Takes care of columns with names like "EntityA.Property1", gets rid of "ows_" prefix:
listData.InnerXml = listData.InnerXml.Replace(
"_x002e_", "_").Replace("ows_", "");

data.DataSet listDataSet = new data.DataSet();
xml.
XmlNodeReader listDataReader = new xml.XmlNodeReader(listData);
listDataSet.ReadXml(listDataReader);
CollectionViewSource dataObj = (CollectionViewSource)Resources["Data"];
dataObj.Source =
new data.DataView(listDataSet.Tables[1]);

}
}
}


Here's the XAML component:

<
Window x:Class="WindowsApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowsApplication1" Height="300" Width="300"
Loaded="OnLoaded"
>

<
Window.Resources>
<
CollectionViewSource x:Key="Data" />
</
Window.Resources>

<
Grid DataContext="{StaticResource Data}">
<
ListBox ItemsSource="{Binding}" DisplayMemberPath="EntityA_Property1"/>
</
Grid>

</
Window>

0 comments: