• home
    • news & events
    • blog
  • über uns
    • projekte und referenzen
    • partner
    • produkte & technologien
    • offene jobs / stellen
    • veröffentlichungen
  • dienstleistungen & services
    • software design & architektur
    • software entwicklung
    • beratung / consulting
    • training, kurse und workshops
  • angebote
    • quick-starts
    • trainings und kurse
    • modulare sharepoint 2010 workshops
  • kontakt
Wir bieten SharePoint und .NET
Kompetenz, Erfahrung und Know-How:
"1stQuad guaranteed."
Diesen Blog abonnieren
Subscribe in NewsGator Online Add to My AOL
Add to Google Reader or Homepage Add to netvibes

Aktuelle Posts

Quick-Tipp: Publishing Site Settings
Update: Dynamisches Wiki Inhaltsverzeichnis
Chart Part für SharePoint 2010
SharePoint Content DB Migration -> Access denied
Konfigurieren von „Gefällt mir“ und Kategorien und Notizen

Archiv

Januar 2012 (4)
Dezember 2011 (2)
November 2011 (10)
September 2011 (3)
August 2011 (7)
Juli 2011 (1)
Juni 2011 (3)
Mai 2011 (6)
April 2011 (5)
März 2011 (8)
Februar 2011 (8)
Januar 2011 (4)
Dezember 2010 (5)
November 2010 (7)
September 2010 (6)
August 2010 (2)
Juli 2010 (11)
Juni 2010 (13)
Mai 2010 (11)
April 2010 (4)
März 2010 (6)
Februar 2010 (2)
Januar 2010 (6)
Dezember 2009 (4)
November 2009 (13)
Oktober 2009 (17)
September 2009 (2)
Juli 2009 (2)
März 2009 (2)
Januar 2009 (1)

1stQuad ist Microsoft Certified Gold Partner und bietet SharePoint und .NET Produkt- und Projekt-Kompetenz, -Erfahrung und -Know-How für Entwicklung, Architektur, Beratung, Schulung, Training und Kurse in Schweiz sowie Deutschland und Östereich.
1stQuad ist MatchPoint Partner und bietet MatchPoint Produkt- und Projekt-Kompetenz, -Erfahrung und -Know-How für Entwicklung, Architektur, Beratung, Schulung, Training und Kurse in Schweiz sowie Deutschland und Östereich.
1stQuad ist Nintex Partner und bietet Nintext SharePoint Workflows Produkt- und Projekt-Kompetenz, -Erfahrung und -Know-How für Entwicklung, Architektur, Beratung, Schulung, Training und Kurse in Schweiz sowie Deutschland und Östereich.
1stQuad ist Balesio Gold Partner und bietet SharePoint FILEMinimizer Produkt- und Projekt-Kompetenz, -Erfahrung und -Know-How für Entwicklung, Architektur, Beratung, Schulung, Training und Kurse in Schweiz sowie Deutschland und Östereich.
1stQuad Solutions ist Kentico Certified Solution Partner und bietet Produkt- und Projekt-Kompetenz, -Erfahrung und -Know-How für Entwicklung, Architektur, Beratung, Schulung, Training und Kurse in Schweiz sowie Deutschland und Östereich.
© 2011 1stQuad Solutions
Alle Rechte vorbehalten
> Impressum
Wir bieten Microsoft SharePoint und .NET Projekt- und Produkt-Know-how, Kompetenz und Erfahrung für Entwicklung, Architektur, Beratung, Schulung, Training und Kurse in Zürich, Bern, Basel, Schweiz sowie Deutschland und Östereich.

Blog > März 2010

SharePoint 2010 Client Object-Model und Silverlight – ein Beispiel

In diesem Beitrag zeige ich anhand eines Beispiels, wie SharePoint-Daten mit Hilfe des neuen SharePoint 2010 Client-Object Model in eine Silverlight 3 Applikation eingebunden werden können.

Veröffentlicht am 27.03.2010 09:16:15 von Michael Hofer mit 0 Kommentar(en)

Eines, der für mich wertvollsten neuen Features von Sharepoint 2010, ist das Client Object Model. Gerade bei der Entwicklung von Silverlight Web Applikationen in Verbindung mit Sharepoint erleichtert es die Arbeit wesentlich, denn bisher mussten umständlich Serveranwendungen entwickelt werden oder über die (unvollständige und umständliche) Sharepoint Webservices zurückgegriffen werden. Das Client Object Model führt eine Abstraktionsschicht ein, welche Zugriffe auf SharePoint Objekte auf gewohnte Art und Weise erlaubt – bei gleichzeitiger Optimierung der Datenübertrag. Wie das geht s möchte ich im folgenden in einem Praxis-Beispiel aufzeigen, doch der Komplettheit halber seien hier noch alle Technologien des Client Object Models aufgeführt:
  • .NET-Clients:  Microsoft.SharePoint.Client.dll (14\ISAPI)
  • Silverlight-Clients:  Microsoft.SharePoint.Client.Silverlight.dll & Microsoft.SharePoint.Client.Silverlight.Runtime.dl l (14\LAYOUTS\ClientBin)
  • JavaScript: SP.js (14\LAYOUTS)
  • In meinem Beispiel möchte ich die Content-Types einer SharePoint Site auslesen und in 2 abhängigen DropDowns anzeigen:
SilverLight-SharePoint-Client-Object-Model.png
 
Zuerst erstelle ich im Visual Studio ein neues Projekt vom Typ „Silverlight“ Applikation. Danach erstelle ich die beiden DropDowns im Designer XAML wie folgt:
 

<UserControl x:Class="SilverlightApplication1.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d"

    d:DesignHeight="300" d:DesignWidth="400" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input" Loaded="UserControl_Loaded">

    <StackPanel Orientation="Vertical">

        <Grid Name="grdContentTypes" Height="Auto">

            <Grid.RowDefinitions>

                <RowDefinition Height="10" />

                <RowDefinition Height="Auto" />

                <RowDefinition Height="Auto" />

                <RowDefinition Height="Auto" />

            </Grid.RowDefinitions>

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="0*" />

                <ColumnDefinition Width="103*" />

                <ColumnDefinition Width="210*" />

            </Grid.ColumnDefinitions>

            <dataInput:Label Height="Auto" HorizontalAlignment="Stretch" Margin="3" Name="lblContenTypeGroups" VerticalAlignment="Center" Width="Auto" Grid.Column="1" Content="Content-Type Group:" Grid.RowSpan="2" />

            <dataInput:Label Grid.Row="2" Height="Auto" HorizontalAlignment="Stretch" Margin="3" Name="lblContentTypes" VerticalAlignment="Center" Width="Auto" Grid.Column="1" Content="ContentType:" />

            <ComboBox Grid.Column="2" Height="Auto" HorizontalAlignment="Left" Margin="3" Name="cboContentTypeGroups" VerticalAlignment="Center" Width="250" Grid.RowSpan="2" SelectionChanged="OnContentTypesGroupChanged" ItemsSource="{Binding}">

                <ComboBox.ItemTemplate>

                    <DataTemplate>

                        <TextBlock Margin="0,0,50,0" Text="{Binding Name}" />

                    </DataTemplate>

                </ComboBox.ItemTemplate>

            </ComboBox>

            <ComboBox Grid.Column="2" Grid.Row="2" Height="Auto" HorizontalAlignment="Left" Margin="3" Name="cboContentTypes" VerticalAlignment="Center" Width="250" ItemsSource="{Binding}">

                <ComboBox.ItemTemplate>

                    <DataTemplate>

                        <TextBlock Text="{Binding Name}" Margin="0,0,50,0" />

                    </DataTemplate>

                </ComboBox.ItemTemplate>

            </ComboBox>

        </Grid>

    </StackPanel>

</UserControl>


 
Nun geht’s in den Code. Als Erstes benötigen wir den SharePoint Client-Context:

public MainPage()
{
    InitializeComponent();
 
    string webUrl = "http://localhost";
    ClientContext = new ClientContext(webUrl);
}
 
public ClientContext ClientContext { get; set; }
 
Weiter geht’s wir brauchen eine Methode um die Content Types auszulesen:
 
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    SetContentTypes();
}
 
In der Methode SetContentTypes wollen wir nun die Content Types des aktuellen Webs laden und diese gruppiert nach Gruppen-Name anzeigen.
 
Client.Context.Web.AvailableContentTypes funktioniert zwar im Intellisense, wir werden aber zur Laufzeit feststellen (respektive eine Fehlermeldung erhalten), das gar keine Content Types über diese Collection abgerufen werden können. Dies liegt daran, dass wir dem ClientContext explizit sagen müssen, dass er diese Daten vom Server abrufen soll! Und nicht nur das, wir können sogar angeben, welche Eigenschaften der Content Types geladen werden sollen:
 
ClientContext.Load(
    ClientContext.Web.AvailableContentTypes,
    contentTypes => contentTypes.Include(
        contentType => contentType.Id,
        contentType => contentType.Name,
        contentType => contentType.Group,
        contentType => contentType.Hidden)
    .Where(contentType => !contentType.Hidden)
   );
 
Über die Methode ClientContext.Load können wir sowohl angeben, welche ContentType-Collection wir laden wollen, wie auch die Eigenschaften und auch noch gleich eine Abfrage/einen Filter.
 
Es gibt 2 Methoden um die Daten zu laden: ClientContext.Query und ClientContext.Load. Beide haben ihre Vor- und Nachteile und ein guter Vergleich finden Sie hier: http://praveenbattula.blogspot.com/2010/03/sharepoint-2010-loadquery-vs-load.html
 
Nun aber weiter: Wir wollen die Daten nun ja auch laden. Hier kommen die Eigenheiten von Silverlight ins Spiel, welche es nicht zulässt, dass wir einfach ClientContext.ExecuteQuery() ausführen. Wir können dies nur in einem von der UI separaten Thread machen, oder aber wir wählen die asynchrone Variante zum Laden von Daten, welche uns die Threading-Arbeit erspart und dies gleich selber übernimmt:
 
ClientContext.ExecuteQueryAsync(delegate(object sender, ClientRequestSucceededEventArgs args)
{
…
}, delegate(object sender, ClientRequestFailedEventArgs args) {
…
});
 
Nun sind die Content Types geladen und wir können sie an unsere DropDowns hängen. Zuerst einmal wollen wir aber die ContentType-Gruppen bilden:
 
cboContentTypeGroups.DataContext = (
    from ct in ClientContext.Web.AvailableContentTypes.ToList<ContentType>()
 
    where ct.Group!="_Hidden"
    group ct by ct.Group into g
    orderby g.Key
    select new ContenTypeGroup { Name = g.Key.ToString(), ContentTypes = g });
 
Kleiner Typ hier: Das .ToList<ContentType>() erscheint unnötig, da ClientContext.Web.AvailableContentTypes bereits eine Collection zurückgibt. Leider gibt es aber zur Laufzeit eine Exception „Method not support“ wenn man gruppiert. Macht man aber aus der SPContentTypeCollection eine generische Liste, dann klappt auch dies.
 
Der Rest ist relativ einfach:

cboContentTypeGroups.IsEnabled = cboContentTypeGroups.Items.Count > 0;
cboContentTypeGroups.SelectedIndex = cboContentTypeGroups.IsEnabled ? 0 : -1;
 
Wenn wir nun das Ganze testen, werden wir eine Threading-Exception erhalten. Macht eigentlich Sinn, denn die Delegate, welche ClientContext.ExecuteQueryAsync aufruft wird ja in einem eigenen Thread ausgeführt. Hier benötigen wir den Dispatcher des SilverLight UserControls. Und so sieht die fertige Methode aus:
 
private void SetContentTypes()
{
    cboContentTypeGroups.IsEnabled = false;
   cboContentTypeGroups.IsEnabled = false;
 
    ClientContext.Load(
        ClientContext.Web.AvailableContentTypes,
        contentTypes => contentTypes
        .Include(
            contentType => contentType.Id,
            contentType => contentType.Name,
            contentType => contentType.Group,
            contentType => contentType.Hidden)
        .Where(contentType => !contentType.Hidden)
        );
 
    ClientContext.ExecuteQueryAsync(delegate(object sender, ClientRequestSucceededEventArgs args)
    {
        Dispatcher.BeginInvoke(() =>
        {
             cboContentTypeGroups.DataContext = (
                from ct in ClientContext.Web.AvailableContentTypes.ToList<ContentType>()
 
                where ct.Group!="_Hidden"
                group ct by ct.Group into g
                orderby g.Key
                select new ContenTypeGroup { Name = g.Key.ToString(), ContentTypes = g });
 
             cboContentTypeGroups.IsEnabled = cboContentTypeGroups.Items.Count > 0;
             cboContentTypeGroups.SelectedIndex = cboContentTypeGroups.IsEnabled ? 0 : -1;
        });
    }, delegate(object sender, ClientRequestFailedEventArgs args) {
        Dispatcher.BeginInvoke(() =>
        {
            cboContentTypeGroups.DataContext = null;
            // TODO ErrorHandling
        });
    });
}
 
Alles, was uns jetzt noch fehlt ist ein Event-Handler für die DropDown-Liste der ContentType-Gruppen OnContentTypesGroupChanged:
 
private void OnContentTypesGroupChanged(object sender, SelectionChangedEventArgs e)
{
    if (cboContentTypeGroups.SelectedItem != null)
    {
        cboContentTypes.DataContext = ((ContenTypeGroup)cboContentTypeGroups.SelectedItem).ContentTypes.OrderBy(ct => ct.Name);
        cboContentTypes.IsEnabled = cboContentTypeGroups.Items.Count > 0;
        cboContentTypes.SelectedIndex = cboContentTypeGroups.IsEnabled ? 0 : -1;
    }
}
 
Fazit: Dieses Beispiel zeigt auf, wie einfach in Silverlight 3 (oder anderen Client-Applikationen) dank des neuen SharePoint 2010 Client Object Model mit den gewohnten SharePoint Klassen wie Web, Site, List etc. gearbeitet werden kann. In Silverlight 3 gibt es allerdings für Server-Seitige-SharePoint-Entwicklung-Gewohnte noch ein paar Schwierigkeiten zu umschiffen – trotzdem: So einfach war client-seitige Integration von SharePoint sicherlich noch nie. Ein grosses Bravo an die Entwickler!
 

Kommentar
Dieser Blog-Eintrag wurde noch nicht kommentiert.
Kommentar hinterlassen



 Security code
Zurück, Seite drucken