14 + x Tage ist das Microsoft Web Camp in München zum Thema: ASP.NET MVC2 nun schon vorbei. Meine Eindrücke des ersten Tages hatte ich bereits im letzten Blogbeitrag, “Microsoft Web Camps (München) – Tag 1″, in Worte gefasst. Für all diejenigen, die sich fragen wie so ein Workshop Tag abläuft, werde ich versuchen den zweiten Tag nocheinmal Revue passieren zu lassen.
Nach einem informativen ersten Tag sollte ein Workshop Tag folgen, an dem das Erlernte sofort in die Praxis umgesetzt werden konnte. Im Bericht über Tag 1 habe ich bereits erwähnt, dass am Ende des ersten Tages Ideen gesammelt wurden welche am zweiten Tag in Projektteams bearbeitet werden sollten. Die Vielfalt an Projektideen war toll. Hier einige Vorschläge:
Unter dem Motto “Make Web, Not War” tourt Microsoft zur Zeit mit seinen Webcamps durch die Welt. Am 07. und 08. Juni (war) ist Zwischenstopp in Unterschleißheim / München. Ich hatte das Glück dabei zu sein. An beiden Tagen haben sich Christian Wenz sowie John Galloway (ASP.NET Community Program Manager) auf die Fahne geschrieben uns die Microsoft Web Platform und die damit verbundenen Tools näher zu bringen. Schwerpunkt lag dabei vor allem auf ASP.NET MVC 2, Entity Framework sowie IIS 7.x.
Diese Wallpaper können hier heruntergeladen werden.
Angekommen im Dolce Munich, im schönen Unterschleißheim, konnte man sich ersteinmal bei einem tollen Kaffee kennenlernen.
Anschließend folgte eine Begrüßung durch Frank Fischer von Microsoft, welcher gleich auch noch ein paar Worte über Microsoft WebsiteSpark und BizSpark verlor.
Im Ersten Teil ging es noch einmal tief in den “Urschleim” zurück. Nach einem Gesamtüberblick über ASP.NET, ASP.NET Webforms sowie Neuerungen in ASP.NET 4 gab es noch einen Überblick über die Micrsoft Web Platform. Danach wurde es interessant. In 3 Teilen haben Christian und John eine “Rich web application” mit MVC und dem Entity Framework erstellt. Vorrangig ging es dabei um die Grundprinzipien der Web Entwicklung mit Model – View – Controller (MVC). Das Beispiel wurde dabei nach und nach zu einer datengetriebenen Anwendung, mit Hilfe des Entity Frameworks weiterentwickelt.
Im zweiten Teil wurden weitere neue Features von ASP.NET MVC 2 vorgestellt. Unter anderem die HTML Helpers, Datenvalidatoren, Templating sowie die Zusammenarbeit mit Visual Stuido 2010.
Letztlich wurde noch gezeigt wie ASP mit jQery zusammenarbeiten kann und wie das Deployment von statten geht. Auch die Verwendung des neuen IIS und dessen IIS Erweiterungen wurde erläutert.
Am Ende des Tages wurden Ideen gesammelt was für Projekte an Tag 2 durchgeführt werden. Dabei kamen viele, teils lustige aber auch teils sehr kreative Ideen zusammen und fanden ihre Anhänger in Form von Teams.
Fazit Tag 1: Für mich hat sich dieser Tag auf jeden Fall gelohnt. Es wurden teilweise sehr interessante Themen vorgestellt, welche direkt mit gecoded werden konnten. Ein bisschen Faden Beigeschmack hatte die schon nostalgische Internetverbindung im Dolce Munich, die teilweise nicht über 5 kbyte hinaus kam. Man wurde direkt an die gute alte Modemzeit erinnert.
Ja Sie haben richtig gelesen: Es ist soweit! Früher als erwartet veröffentlicht Microsoft die finale Version seiner beiden Flagschiff – Produkte. Ab sofort sind der Sharepoint Server 2010 sowie Microsoft Office 2010 über das Developer Network zu beziehen. Ebenfalls erschienen sind Microsoft Project 2010 sowie Visio 2010.
http://msdn.microsoft.com/subscriptions/downloads/
Ebenfalls stehen die SharePoint Foundations 2010 sowie der SharePoint Designer 2010 ab sofort zum kostenlosen Download bereit und besitzen nicht länger ihren Beta Status.
Wollen wir hoffen, dass die letzten Bugs noch entfernt wurden.
Die kostenlosen Varianten der Produkte (SharePoint Foundation) können hier herunter geladen werden:
SharePoint Foundation 2010 – http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=49c79a8a-4612-4e7d-a0b4-3bb429b46595
SharePoint Designer 2010 x64 - http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=566d3f55-77a5-4298-bb9c-f55f096b125d
SharePoint Designer 2010 x86 – http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=d88a1505-849b-4587-b854-a7054ee28d66
Wie werden nun diese Sharepoint Listen gezeichnet? Wie könnte nun der neu zu entwickeltende, spektakuläre Cover Flow für Sharepoint aussehen, den man sich gerade noch im Kopf zurecht gerückt hat? Irgendwie muss dieser im Kopf entwickelte Prototyp nun in das Konzept übertragen werden. Spätestens an diesem Punkt steigen die meisten Consultants oder Artgenossen aus. Einige versuchen sich noch hartnäckig mit ihren Copy & Paste Fähigkeiten (Photoshop und Co.) das gewünschte Bild zusammen zu montieren. Aber sind wir doch mal ehrlich: schön ist das nicht.
Wer öfters mal eine Dokumentation oder aber auch ein Fachkonzept schreibt, wird dieses Szenario wahrscheinlich nur zu gut kennen.
Die kleine italienisch/amerikanische Firma Balsamiq Studios hat sich auf die Flagge geschrieben, uns genau in dieser schweren Zeit der “Ideen-Illustration” zu unterstützen. Gegründet und geleitet wird die kleine Firma von Giacomo ‘Peldi’ Guilizzoni, einem Ex – Adobe Software Lead. Mehr über die Gründungsgeschichte von Balsamiq kann in diesem (empfehlenswerten) Blogpost gefunden werden.
Wie sieht so eine “Skizze”, welche mit Balsamiq entworfen werden kann, denn nun aus?
Genau so!
Am 24.02.2010 haben sich die .NET Freaks aus Dresden und Umgebung zur .NET Usergroup bei uns im Hause zusammen gefunden. Diesmal wurde es gruselig. Alexander Groß führte uns durch ein aktuelles Projekt, welches sich rund um die Bestattung und Einäscherung dreht. Die Idee des Vortrages, welcher eigentlich kein Vortrag im engeren Sinne darstellte, war die gemeinsame Betrachtung eines aktuellen Projektes und deren verwendeten Techniken.
Schon nach einigen Minuten kam es zu interessanten Diskussionen.
Alexander zeigte beispielsweiße wie in seinem Projekt Rake verwendet wird um auf einfache Weise Konfigurationen leicht wartbar zu halten. Außerdem wie Rake und MSDeploy zusammen ein super Team darstellen um Anwendungen zu deployen.
Dem Einen oder Anderen hat Visual Studio wahrscheinlich schon einmal mit dieser leicht dominierenden Bildschirmausgabe überrascht. Wahrscheinlich aber haben es die Meisten noch nie zu Gesicht bekommen, denn wir sind ja keine Copy & Paste Entwickler.
Das ist der besagte Hinweis:
Randbedingungen:
Ich verwende eine virtuelle Maschine(Windows Server 2003) unter Microsoft Virtual Server 2005 R2.
Das Problem tritt gelegentlich auf, wenn innerhalb der Host Maschine etwas kopiert wird und anschließend versucht wird, das soeben kopierte, in Visual Studio, auf der Entwicklungsmaschine, einzufügen.
Lösung:
Wie kann dieses Problem nun gelöst werden? Anfangs dachte ich, der Übeltäter wäre Visual Studio, und beendete einfach den devenv.exe Prozess. Irgendwann irritierte es mich aber, dass sobald diese Meldung auftauchte überhaupt kein Copy & Paste mehr funktionierte. Zu diesem Zeitpunkt fand ich heraus, dass der eigentliche, anfangs nicht verdächtige, Prozess rdpclip.exe der Schuldige war.
Um also in Visual Studio weiter arbeiten zu können, muss einfach der Prozess rdclip.exe beendet werden. Dies kann leicht über den Task Manager vollführt werden.
Falls anschließend wieder Copy & Paste verwendet werden soll, nicht vergessen den RdpClip.exe Prozess wieder zu starten. Gefunden werden kann dieser im Verzeichnis C:\Windows\System32
Jetzt ist schon fast ein halbes Jahr vergangen, als ich mich das letzte Mal mit dem Cross Site Scripting Filter (XSS) von Sharepoint 2007 befasst habe. Dieser stellt einen wesentlichen Bestandteil von Sharepoint dar und bereitete mir damals schon sehr viele Kopfschmerzen. Prinzipiell besteht die Aufgabe des XSS Filters darin, schädlichen Code oder Skripte aus dynamisch generierten HTML Seiten zu entfernen. Dass der Filter manchmal etwas willkürlich arbeitete hatte ich damals in meinen Blogbeitrag bereits gezeigt.
Was bisher geschah: Sharepoint und der eigensinnige XSS – Filter (Bericht)
Grund genug, sich einmal die Unterschiede zwischen Sharepoint 2007 und Sharepoint 2010 anzuschauen.
Um die Unterschiede zu verdeutlichen, habe ich ein HTML Quelldokument, jeweils mit einem Sharepoint 2007 und mit einem Sharepoint 2010 Server programmatisch importiert.
Folgender Programmcode kam dabei zum Einsatz.
class Program
{
static void Main(string[] args)
{
using (SPSite site = new SPSite("http://....."))
{
using (SPWeb web = site.OpenWeb())
{
PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(web);
string pageFileName = "Test";
PageLayout[] pageLayouts = pubWeb.GetAvailablePageLayouts();
PageLayout currPageLayout = pageLayouts[4];
PublishingPageCollection pages = pubWeb.GetPublishingPages();
PublishingPage currentPage = pages.Add(string.Concat(pageFileName,".aspx"),currPageLayout);
string htmlContent = GetFileContent();
currentPage.ListItem[FieldId.PublishingPageContent] = htmlContent;
currentPage.ListItem.Update();
currentPage.Update();
currentPage.CheckIn("Checked in by me");
}
}
}
Die Ergebnisse des Tests zeigt die folgende Tabelle.
Positiv fällt auf, dass Sharepoint 2010 endlich die Anführungszeichen an Attributen unangetastet lässt. Die 2007 er Version löschte derartige Zeichen kompromisslos weg. Kommentare akzeptiert Sharepoint 2010 immer noch nicht als HTML Elemente – sie werden ebenfalls gelöscht. <li> Elemente dürfen keine Bilder als Listen Icons besitzen. Möchte man sein eigenes Icon zu einer Liste hinzufügen sollte auf eine externe CSS Klasse zurück gegriffen werden (Dies ist in jedem Falle zu empfehlen). Die Eigenschaften “inherit” sowie “none” hingegen werden unterstützt.
Script Tags werden völlig korrekt entfernt. Ebenso Iframe Elemente. Diese sind nicht erwünscht.
Weiterhin positiv aufgefallen ist, dass Elemente des Typs <input/> endlich korrekt geschlossen werden. Das Attribut “Name” wird leider gelöscht. Warum kann ich mir nicht erklären, es scheint aber so, als würden alle Attribute mit der Bezeichnung “name” gelöscht.
Als letzte Besonderheit fällt auf, dass Sharepoint nun konsequent alle absoluten Urls in relative überführt. In Sharepoint 2007 blieben absolute Urls unangetastet. Relative Urls, welche keinen Bezug zu dem aktuellen Sharepoint Server besitzen, wie etwa <a href=”../../beispiel.htm”>, werden weiterhin gelöscht.
Fazit: Es scheint als hätte sich das Sharepoint Entwicklungsteam einige Gedanken über XHTML & Co gemacht. So fallen die geschlossen Tags sowie die Anführungszeichen positiv auf. Einige Baustellen bleiben weiterhin offen.
Im vorangegangenen Blogbeitrag über das Client object model, habe ich beschrieben wie mittels Context.Executequery() eine synchrone Anfrage an den Sharepoint Server abgesetzt werden kann. In diesem Eintrag werde ich das Gegenstück Context.ExecuteQueryAsync() etwas näher beleuchten. Es ist etwas verwirrend, dass Microsoft hier zwei Methoden anbietet, um Anfragen an Sharepoint zu senden. Als ich erstmalig die Methode ExecuteQuery() aufgerufen habe, erhielt ich eine Exception, welche mir mitteilte, dass ich diese Methode nicht in einem UI Thread aufrufen darf.
InvalidOperationException. The method or property that is called may block the UI thread and it is not allowed.
Aus diesem Grund, muss bei Verwendung der Methode ExecuteQuery(), in einem UI Prozess, ein Thread gewählt werden, welcher das UI nicht beeinträchtigt.
ThreadPool.QueueUserWorkItem(new WaitCallback(LoadSharepointContext));
Nach einer kurzen Suche bin ich auf die Erklärung der MSDN gestoßen.
The Silverlight client object model provides both an ExecuteQuery() method, which can be called synchronously from threads that do not modify the user interface (UI), and an asynchronous ExecuteQueryAsync(ClientRequestSucceededEventHandler, ClientRequestFailedEventHandler) method for cases where threads do modify the UI
Soll das Laden der Sharepoint Daten in einem User Interface Thread erfolgen, muss also zwingend die Asynchrone Methode verwendet werden. Falls der Programmcode keine Änderung an der UI vornimmt, kann weiterhin die synchrone Methode verwendet werden. Wie die asynchrone Query zu verwenden ist, zeige ich im nachfolgendem Beispiel.
Voraussetzungen für dieses Beispiel:
Die Voraussetzungen für dieses Beispiel sind analog der, des ersten Blogeintrages:
Los geht’s:
1. Es sind die Schritte 1. – 6. des Blogeintrages “Sharepoint 2010: Client object model & Silverlight – synchroner Ansatz” auszuführen.
2. Die Abarbeitung der Query varriert jedoch zu dem synchronen Ansatz.
ClientContext clientCxt = new ClientContext("http://siteCollectionAdresse");
List shoppingList = clientCxt.Web.Lists.GetByTitle("Einkauf");
CamlQuery query = CamlQuery.CreateAllItemsQuery();
ListItemCollection listItems = shoppingList.GetItems(query);
clientCxt.Load(listItems);
clientCxt.ExecuteQueryAsync(new ClientRequestSucceededEventHandler(OnSuccess), new ClientRequestFailedEventHandler(OnFailed));
Wie zu erkennen, wird diesmal die Methode “ExecuteQueryAsync” aufgerufen. Diese benötigt als Paramater einen ClientRequestSucceededEventHandler sowie einen ClientRequestFailedEventHandler. Beide werden wie folgt erzeugt:
private void OnSuccess(Object sender, ClientRequestSucceededEventArgs args)
{
}
private void OnFailed(Object sender, ClientRequestFailedEventArgs args)
{
}
3. Bei erfolgreicher Abarbeitung der Anfrage, sollte diese im Successhandler landen, wo die weitere Verarbeitung der Daten stattfinden kann.
private void OnSuccess(Object sender, ClientRequestSucceededEventArgs args)
{
foreach (ListItem item in listItems)
{
einkaufList.Add(new EinkaufData
{
Title = item["Title"].ToString(),
Details = item["Details"].ToString(),
Preis = item["Preis"].ToString()
});
}
}
4. Achtung: Die Verarbeitung in OnSuccess findet in einem separaten Thread statt (nicht UI Thread). Nimmt man Änderungen an dem User Interface vor, muss der Dispatcher verwendet werden.
disp.BeginInvoke(() =>
{
dataGrid.ItemsSource = einkaufList;
});
5. Ist alles erfolgreich geladen, sollte das Datagrid wie folgt aussehen.
Eines, der für mich meist erwarteten Features von Sharepoint 2010, ist das neue Client object model. Gerade hinsichtlich der Entwicklung von Silverlight Web Applikationen in Verbindung mit Sharepoint, erleichtert es uns deutlich die Arbeit. Bisher mussten umständlich Serveranwendungen geschrieben werden um dann per Sharepoint Webservices auf die API zurück zu greifen. Das Client object model zieht nun eine neue Abstraktionsschicht ein, um diese Zugriffe zu erleichtern. Mit Hilfe des Client object models stehen fast alle Eigenschaften und Daten einer Site Collection zur Verfügung, so zum Beispiel der Zugriff auf Listen.
Das Client object model steht für nahezu alle Technologien zur Verfügung. Ob WPF, Forms Anwendungen, Silverlight oder Javascript.
In diesem ersten Überblick zeige ich wie das Client object model verwendet werden kann, um Daten aus einer Sharepoint 2010 Liste auszulesen. Das Auslesen der Daten soll in einer Silverlight Web Applikation stattfinden. Diese soll nicht, wie in den meisten Beiträgen zum Client object model, in Form eines Sharepoint Webparts erstellt werden, sondern außerhalb von Sharepoint laufen.
Voraussetzungen für dieses Beispiel:
Los geht’s:
1. Im ersten Schritt muss ein neues Silverlight 3 Projekt innerhalb von Visual Studio angelegt werden. Zum Beispiel Silverlight 3 Navigation Application.
2. Die folgenden beiden DLLs werden als Referenz in dem Silverlight Projekt benötigt.
Wenn Visual Studio 2010(Beta 2) verwendet wird und nach dem Hinzufügen der beiden DLLs ein kleines rotes Ausrufezeichen an der Referenz kleben sollte, habt ihr nichts falsch gemacht. Dabei handelt es sich um einen Bug von Visual Studio 2010. Der Fehler ist in der Pfadtiefe des Projektes und der Silverlight DLLs begründet. Um den Fehler zu beheben habe ich das Projekt einfach unter C:\Projects gelegt.
3. Da sich Sharepoint 2010 und das Silverlight Projekt in einer unterschiedlichen Domain befinden, wird der Zugriff auf den Client Context verweigert. Silverlight benötigt eine Clientaccesspolicy.xml Datei welche bestimmt, ob der Zugriff autorisiert ist. Diese Datei muss sich im Rootverzeichnis des Webservers befinden. Hier kommen die domain policy helper von Tim Heuer ins Spiel. Innerhalb des Webprojektes der Silverlightanwendung wird eine XML Datei mit den Namen Clientaccesspolicy.xml erstellt.
In dieser Datei wird das Snippet Menü via STRG+K+X aufgerufen und das Silverlight Clientaccesspolicy.xml Snippet ausgewählt. Der folgende Inhalt sollte erscheinen.
Wichtig: Vor Verwendung der Datei muss ein IIS Reset erfolgen.
4. Auf der darstellenden Seite benötigen wir ein Anzeigeelement für die Listen Daten. Dazu empfiehlt sich ein Datagrid. Dieses kann, basierend auf einem Datenobjekt, seine Spalten dynamisch generieren.
<data:DataGrid AutoGenerateColumns="True" Height="200" Name="einkauf" Width="311" HorizontalAlignment="Left" />
Mit diesem XAML Code wird ein Datagrid mit dem Namen “einkauf” erstellt, welches automatisch seine Spalten generiert.
5. Auf Basis der Sharepoint Liste wird ein Datenobjekt erstellt.
public class EinkaufData
{
public string Title {get;set;}
public string Preis { get; set; }
public string Details { get; set; }
}
Dieses wird benötigt um das “einkauf” Datagrid zu befüllen.
6. Basierend auf dem Datenobjekt wird eine Liste erstellt.
private List einkaufList = new List();
7. Wie im Titel erwähnt, nutze ich in diesem Beispiel die synchrone Datenübertragung. Für synchrone Anfragen wird die Methode ExecuteQuery() genutzt, für asynchrone ExecuteQueryAsync . ExecuteQuery darf nicht eingesetzt werden, falls damit das Laden des User Interfaces beeinträchtigt wird. Falls die Methode trotzdem verwendet wird, tritt folgende Exception auf.
InvalidOperationException. The method or property that is called may block the UI thread and it is not allowed.
Um dieser Exception aus dem Weg zu gehen, wird die Methode LoadSharepointContext in einem Hintergrundprozess ausgeführt.
ThreadPool.QueueUserWorkItem(new WaitCallback(LoadSharepointContext));
private void LoadSharepointContext(Object stateInfo)
{
ClientContext clientCxt = new ClientContext("http://siteCollectionAdresse");
List shoppingList = clientCxt.Web.Lists.GetByTitle("Einkauf");
CamlQuery query = CamlQuery.CreateAllItemsQuery();
ListItemCollection listItems = shoppingList.GetItems(query);
clientCxt.Load(listItems);
clientCxt.ExecuteQuery();
foreach (ListItem item in listItems)
{
einkaufList.Add(new EinkaufData
{
Title = item["Title"].ToString(),
Details = item["Details"].ToString(),
Preis = item["Preis"].ToString()
});
}
}
8. War das Laden des Sharepoint Kontextes erfolgreich, sollte die einkaufList nun mit den Daten der Sharepoint Liste gefüllt sein.
Als letzter Schritt muss nun die Liste dem Datagrid als Quelle zur Verfügung gestellt werden. Dabei muss beachtet werden, dass die Liste nicht im User Interface Thread befüllt wurde. Hier kommt der Dispatcher zum Zug.
Dispatcher.BeginInvoke(() =>
{
einkauf.ItemsSource = einkaufList;
});
9. War alles erfolgreich sollte das Datagrid wie folgt aussehen.
Tipp: Sollte ein Zugriff auf eine Eigenschaft eines SP Objektes erfolgen, ohne die Query vorher abgesetzt zu haben, erhält man die folgende Exception :
PropertyOrFieldNotInitializedException. Diese Exception tritt solange auf, bis eine Eigenschaft geladen und die Query mittels ExecuteQuery abgesetzt wurden ist.
Wie die asynchronen Anfragen an Sharepoint mit dem Client object model realisiert werden, zeige ich im nächsten Blogeintrag.
Für alle, die sich mit dem neuen Visual Studio und dem .NET Framework 4.0 vertraut machen wollen oder mehr erfahren möchten, hat Microsoft das neu aktualisierte Visual Studio 2010 and .NET Framework 4 Training Kit veröffentlicht. Das am 11.01.2010 veröffentlichte 151 MB große Paket enthält eine Vielzahl von Präsentationen, Demos und Tutorials. Genau genommen 17 Präsentationen, 21 Demos und 26 Tutorials sowie 10 Videos. In dieser Version des Kits wird auch auf die Themen Office, SharePoint und Application Lifecycle Management eingegangen. Der Download lohnt sich auf alle Fälle.