Real-World SharePoint: SharePoint Logging Datenbank

Von Andreas Aschauer Autor Feed 27. March 2011 15:52
Dieser Post ist Teil 2 der Logging Reihe, in der ich alte und neue Möglichkeiten der Ablaufverfolgung in SharePoint 2010 vorstelle. In Teil 1 wurden die Techniken vorgestellt um selbst in die sogenannten ULS Logs von SharePoint zu schreiben und so die Abläufe und Fehler in eigenen SharePoint Applikationen (Composites) nachzuvollziehen, wenn keine Debugging Möglichkeiten gegeben sind (so wie es auf Staging und natürlich Produktionssystemen der Fall ist). In diesem Teil soll die neue Logging Datenbank von SharePoint 2010 vorgestellt werden. Das Durchsuchen der ULS Logs kann mitunter eine mühsame Arbeit sein, je nachdem wie “verbos” die jeweilige SharePoint Farm ihre Aktivitäten mit-logged. Was und besonders wie viel (also welcher Log-Level) jede einzelne Komponenten protokolliert wird seit jeher in der Zentraladministration eingestellt (in SP 2010 unter Monitoring > Diagnostic Logging). Trotzdem, die ULS Logs sind gross und unübersichtlich. Tools wie der bekannte SharePoint ULS Log Viewer helfen zwar dabei, die Protokolle sinvoll durchsuchbar zu machen, aber es muss einen besseren Weg geben in Zeiten hochperformanter relationaler DBMS diese Information zu inidzieren und zu durchsuchen. In SharePoint 2010 gibt es das – Die neuen Logging Datenbanken, direkt im, der Farm zugewiesenen, SQL Server abgelegt. Standardmässig werden von SharePoint 2010 keine Logging Datenbanken angelegt. Um dies zu erreichen müssen einige Timer Jobs, welche für das Logging zuständig sind gestartet werden. Diagnostic Data Provider: Event Log Diagnostic Data Provider: Performance Counters - Database Servers Diagnostic Data Provider: Performance Counters - Web Front Ends Diagnostic Data Provider: SQL Blocking Queries Diagnostic Data Provider: SQL DMV Diagnostic Data Provider: SQL Memory DMV Diagnostic Data Provider: Trace Log Je nachdem was benötigt wird, startet man den entsprechenden Timer Dienst und bekommt sofort eine schöne Logging Datenbank erstellt mit den entsprechenden Protokollen. Diese Informationen zu durchsuchen und zu visualisieren ist ein Leichtes – ein bisschen Programmiererfahrung genügt um auf einen SQL Server zuzugreifen. Hier mit LINQ2SQL 1: public IEnumerable<TraceLog> GetTraceLogEntries() 2: { 3: var ctx = new LoggingDbDataContext(ConnectionFactory.GetTraceLogConnection()); 4: return from logEntry in ctx.TraceLogs 5: select logEntry; 6: } Es ginge noch kürzer, aber wir Entwickler, die in der echten Welt, ausserhalb von “Hello World”, auch schon mal für einen echten Kunden entwickeln, wissen warum Datenbindung nicht in die UI gehört, genauso wie zum Glück mein Baumeister weiss, dass die Wände meines Hauses schichtenweise aufgebaut gehören und nicht alles pragmatisch ineinander vermischt, wie es die Bauarbeiter am liebsten gemacht hätten – das Haus steht in beiden Fällen, aber irgendwie hab ich so das Gefühl dass es auch standhält und sein Geld wert ist. Zurück zum Thema: Diesen kleinen Datenzugriffsblock kann man natürlich wunderbar in ein eigenes WebPart einbauen und hat so sehr komfortabel Zugriff auf die relevanten Logging Daten. Noch besser wäre die entsprechende Datenbank via Business Connectivity Services anzusprechen und als Externen Inhaltstyp verfügbar zu machen. Solange sinnvoll möglich sollte man immer SharePoint OOB Funktionalität verwenden um einfach wartbare und besonders einfach migrierbare Composites zu entwicklen. Das folgende Snippet zeigt die einfachst implementierten Methoden der BDC Entität. Die zwei Methoden reichen um Kompletten Lesezugriff für den externen Inhaltstyp herzustellen 1: public static TraceLog ReadItem(string id) 2: { 3: return GetTraceLogEntries().Where(t => t.CorrelationId == new Guid(id)).Single(); 4: } 5:  6: public static IEnumerable<TraceLog> ReadList() 7: { 8: return GetTraceLogEntries(); 9: } Dieser kurze Überblick versteht sich als Denkanstoss wie man als Entwickler einfach und effizient die SharePoint Logging Daten verarbeiten kann. Eine ausührlichere Demo zu den Business Data Connectivity Services folgt. UPDATE: Da fehlten wohl die Code Snippets – fixed.

LightUp Sharepoint Roadshow–am 15.März in Wien

Von Petra Kleiber Autor Feed 28. February 2011 12:00
Auf einen Blick Kostenloser Event, der Ihnen zeigt wie Sie mehr Nutzen aus einer bestehenden SharePoint-Lösung in Ihrem Unternehmen herausholen können Dienstag den 15.03.2011 von 12:30 -17:30 Microsoft Innovation Center, Am Europlatz 2, 1120 Wien, Österreich Worum geht es? SharePoint bietet bereits von Haus aus eine große Anzahl von Funktionen, kann aber noch weit mehr! Indem Sie Daten und Informationen Ihres Unternehmens besser visualisieren oder Geschäftsanwendungen direkt in SharePoint integrieren steigern Sie noch mehr die Effizienz ihrer MitarbeiterInnen. SharePoint ist eine sehr leistungsfähige Plattform für Geschäftsanwendungen aller Art. Dank Visual Studio 2010 ist es einfacher als je zuvor Anwendungen für SharePoint 2010 zur Visualisierung oder zur Integration in bestehende Geschäftsprozesse zu erstellen. In dieser Veranstaltung zeigen wir Ihnen das Zusammenspiel und die Möglichkeiten von SharePoint 2010, Visual Studio 2010, Team Foundation Server, sowie Technologien wie Silverlight. Viele Live-Demonstrationen werden Sie  inspirieren und Ihnen neue Ideen und Impulse geben, wie aus einem bestehenden SharePoint-Investment noch mehr herausgeholt werden kann. Diese Veranstaltung stellt Dienstleistungen im SharePoint und Application Lifecycle Managment (ALM) Umfeld vor und bietet die Gelegenheit, in einem ungezwungenem Umfeld  Fragen zu stellen. Die Veranstaltung richtet sich gleichermaßen an bestehende SharePoint-Anwender und Neulinge, und setzt keinerlei Vorkenntnisse voraus

Event

Tags:  Feed Tag

Real-World SharePoint Entwicklung: Logging und Fehlerbehandlung in SharePoint 2010– Teil 1

Von Andreas Aschauer Autor Feed 21. January 2011 14:30
Als SharePoint Entwickler ist man es gewohnt umfangreiche Trace Logs und und das Windows Event Log durchzukämmen. Besonders die Informationen welche von SharePoint in die Trace Log Dateien im 14-Hive unter \LOGS, sind extrem umfangreich, je nach den Einstellungen in der Farm. Auf dem eigenen virtuellen Entwicklungsserver mag das durcharbeiten der Log Dateien noch erträglich sein – besonders mit nützlichen Tools wie dem ULS Log Viewer. Wird die eigene Solution dann auf ein Test/Staging System ausgerollt und das Testen geht so richtig los, hört der Spass dann meist auf. Die Logs jedes mal via RDP öffnen oder irgendwie kopieren und durchkramen ist mühsame Arbeit. In diesem un den folgenden Posts wollen wir uns mehrere Dinge ansehen welche uns das Logging Leben erleichtern sollen in SharePoint 2010. - Eigene Informationen via ULS in die Trace Logs schreiben - Die Trave Logs effizient verwalten und einfach durchsuchen Eigene Informationen via ULS loggen Das Einbringen von eigenen Logging Informationen ist eigentlich erfrischend einfach – man glaubt es kaum, aber in den Weiten des Internets kursieren viele Beispiele, welche Unmanaged Code und die Windows API dazu verwenden. Im folgenden ein klassisches “Hello World” Beispiel, wie mit der SharePoint API direkt in SharePoint Server Trace Logs geschrieben werden kann. Logging “Hello World” Beispiel Zuerst ist eine Referenz auf die Assembly Microsoft.Office.Server erforderlich Diese Assembly ist teil von SharePoint SERVER – also auf Systemen, welchen lediglich die Gratis “SharePoint Foundation” besitzen nicht verfügbar. Über die statische Klasse PortalLog im Namespace Microsoft.Office.Server.Diagnostics wird direkt ins Trace Log geschrieben. 1: void LogMessage(string message) 2: { 3: Microsoft.Office.Server.Diagnostics.PortalLog.LogString(message); 4: } Einfacher gehts kaum! Interessant ist bei SharePoint basierten Solutions oft auch, welche Methode aufgerufen wurde im Custom Code – zum Beispiel wenn Event Receiver zum Einsatz kommen. Den Aufruf und das Verlassen einer Methode logged man wie in Beispiel 2. 1: void LogMessage(string message) 2: { 3: Microsoft.Office.Server.Diagnostics.PortalLog.EnterFunction("SPLoggingSample.WebParts.LogMessage"); 4: Microsoft.Office.Server.Diagnostics.PortalLog.LogString(message); 5: Microsoft.Office.Server.Diagnostics.PortalLog.LeaveFunction("SPLoggingSample.WebParts.LogMessage"); 6: } Will man das Loggin in einem try..catch Block verwenden, sollte man immer darauf achten, nach dem entsprechenden Loging Code eine Instanz von SPException zu werfen, damit SharePoint auf den Fehler mit einer Fehlerseite für den User reagieren kann. 1:  2: void DoSomething() 3: { 4: try 5: { 6:  7: } 8: catch (Exception ex) 9: { 10: LogMessage("Error in DoSomething()" + ex.Message); 11: throw new SPException(@"Ein Fehler ist aufgetreten. Die Fehlerinformationen wurden protokolliert. 12: Kontaktieren sie ihren Administrator"); 13: } 14: } SharePoint reagiert automatisch auf eine SPException mit der bekannten weissen Fehlerseite. Das Austauschen von eingabauten SharePoint Application Pages, wie der “Access Denied” Seite oder eben der obigen Fehlerseite, war bisher nur möglich in dem die entsprechenden ASPX Seiten im _layouts Ordner verändert wurden. Mit SharePoint 2010 gibt es die Möglichkeit Systemseiten im Code zu verändern, am besten beim Aktivieren des entsprechenden Features. 1: public override void FeatureActivated(SPFeatureReceiverProperties properties) 2: { 3: var webApp = properties.Feature.Parent as SPWebApplication; 4: if (webApp != null) 5: { 6: // Set Access Denied. 7: if (!webApp.UpdateMappedPage(SPWebApplication.SPCustomPage.AccessDenied, 8: "/_layouts/CodeForceErrorPages/AccessDenied.aspx")) 9: { 10: throw new ApplicationException("Failed setting new access denied page mapping."); 11: } 12:  13: // Set Signout. 14: if (!webApp.UpdateMappedPage(SPWebApplication.SPCustomPage.Signout, 15: "/_layouts/CodeForceErrorPages/Signout.aspx")) 16: { 17: throw new ApplicationException("Failed setting new signout page mapping."); 18: } 19:  20: // Set File Not Found. 21: webApp.FileNotFoundPage = "/_layouts/CodeForceErrorPages/FileNotFound.htm"; 22:  23: webApp.Update(true); 24: } 25: } Das Schöne hierbei ist, dass sich die Änderungen nur auf eine Anwendung beziehen! Soweit das einfachste Logging Szenario – hilft aber bei Problemen welche in Custom Code stecken schon sehr gut weiter um Fehler nachzuvollziehen. Im nächsten Artikel sehen wir uns die neuen Dienste welche SharePoint 2010 zum Thema Logging bietet genauer an. Danach soll ein WebPart – ein LogViewer – erstellt werden, der uns direkt in der Weboberfläche ein Betrachten und Filtern der Logeinträge ermöglicht. In Teil 3 zu guter Letzt gehe ich dann noch auf selbst entwickelte Logging Provider ein, die es zB ermöglichen Fehlermeldungen via WebService zu versenden. Stay tuned for more Up-Front SharePoint Development! Andreas Aschauer

Real-World SharePoint Entwickung: RunWithElevatedPrivileges() verstehen

Von Andreas Aschauer Autor Feed 12. December 2010 00:14
Eins der bekanntesten Konstrukte, das jeder SharePoint Entwickler täglich braucht ist vermutlich SPSecurity.RunWithElevatedPriviliges( () => {…}); Der Aufruf dient dazu einen Codeblock unter erhöhten Rechten auszuführen, was oft dienlich ist, da natürlich jeglicher Code sonst unter den Rechten des aktuell angemeldeten Users ausgeführt wird, welcher meist nur eingeschränkte Rechte hat. Was tut RunWithElevatedPrivileges() eigentlich? Es führt den übergebenen Code unter dem Account “System Account” aus. Dieser User ist ein SharePoint internes Benutzerkonto welches sozusagen im “God-Mode” arbeitet und alles darf. So weit, so gut. Doch in der Praxis sieht das anders aus. Oft treten, trotz dem Aufruf, Exceptions auf, welche besagen, dass man nicht genügend Rechte hat eine Operation auszuführen. Wie kann das sein? Der “System Account” wird auf ein echtes AD Benutzerkonto gemapped, nämlich standardmässig auf die Application Pool Identity. Dieses Konto kann man in IIS Manager einsehen und einstellen. Siehe Abbildung 1 & 2 Abbildung 1 – Application Pool / Advanced Settings Abbildung 2 – Advanced Settings Dialog mit Application Pool Identity Um das Pseudo-Konto SHAREPOINT\system auf ein selbst definiertes AD Konto zu mappen muss lediglich in der Zentraladministration unter Application Management –> Manage Web Applications –> User Policy ein Konto editiert oder neu hinzugefügt werden mit der Einstellung “Account operates as System” und “Full Control”. Hoffentlich lösen sich mit diesem kurzen Tipp einige der Dinge, auf die man im täglichen Entwickeln mit SharePoint stösst. Andreas Aschauer

Real-World SharePoint Entwicklung: Arbeiten mit dem ServiceLocator aus der SharePoint Guidance Library

Von Andreas Aschauer Autor Feed 5. November 2010 12:51
Im letzen Post “Logging mit der SharePoint Guidance Library” wurde, um einen Logger für SharePoint zu erstellen schon kurz der Service Locator erwähnt. Nun wollen wir uns genauer mit dem Locator beschäftigen und in einem Beispiel erarbeiten wozu das Service Locator Pattern verwendet werden kann und welche Probleme es löst. Modulare, test- getrieben entwickelter Code ist der Grundstein für professionelle Softwareentwicklung. Um lose gekoppelte, testbare und vor allem erweiter- und wartbare Software aus einzelnen Komponenten zu erstellen müssen Abhängigkeiten zwischen Komponenten und auch zu externen Systemen entfernt werden. Jegliche fix verdrahtete Abhängigkeit erschwert sofort das Testen und führt zu einer starren Architektur. Eine solche Abhängigkeit ist sehr schnell erzeugt – das beste Beispiel hierfür ist das new() Schlüsselwort. Jeder verwendet es um Instanzen zu erzeugen. Das Erzeugen konkreter Instanzen jedoch ist bindet Komponenten aneinander. Folgender Code erläutert diesen Umstand. 1: public void CreateInvoice(Product product, Address address) 2: { 3: var calc = new ShippingCostCalculator(); 4: product.ShippingCost = calc.CalculateCost(address); 5: } In der Methode wird ein konkreter Konstruktor aufgerufen und somit sind die beiden Klassen fix aneinander gebunden. Noch schlimmer – die Klasse welche CreateInvoice() enthält, ist an die konkrete Implementierung der Klasse ShippingCostCalculator gekoppelt. Sollte sich etwas an der Berechnungslogik ändern, muss bestehender Code umgeschrieben und neu kompiliert werden. Ein Austauschen der Komponenten ist ebenfalls nicht möglich. Das Service Locator Pattern ist eine Möglichkeit solche Kopplung zu vermeiden. Ganz einfach ausgedrückt werden dabei Dienste (Services), welche benötigt werden auf Implementierung gemapped. Ein Service wäre in diesem Fall der ShippingCostCalulator. Eine saubere Implementierung mittels des Patterns würde folgendermassen aussehen. 1: public void CreateInvoice(Product product, Address address) 2: { 3: var calc = ServiceLocator.Current.GetInstance(typeof (IShippingCostService)); 4: product.ShippingCost = calc.CalculateCost(address); 5: } Was hat sich geändert? Die konkrete Instanz von ShippingCostCalculator wird nicht mehr verwendet, somit ist die direkte Abhängigkeit von einer Implementierung entfernt. Anstelle des new() Aufrufes tritt der Service Locator. Der Locator nimmt den Typ eines Services entgegen. Services werden als Interfaces dargestellt. Ein Interface definiert welche Methoden ein Service öffentlich anbietet. Der Service Locator hat ein internes Mapping (wird unten beschrieben) welches Services (Interfaces) auf deren Implementierung mapped. Was wurde erreicht? Der gesamte Code arbeitet gegen Services (Interfaces). Es gibt EINEN zentralen Ort an dem festgelegt wird welche Interfaces von welchen konkreten Implementierungen realisiert werden. Somit ist es möglich OHNE Änderungen im Produktivcode, die Implementierungslogik von IShippingCostService auszutauschen. Arbeiten mit dem Service Locator aus der SharePoint Guidance Library Der Service Locator aus der Library erlaubt es Mappings auf SPSite und auf SPFarm Ebene festzulegen. Das heisst jede SiteCollection kann eigene Services implementieren. Um einen Locator zu erzeugen existieren mehrer Möglichkeiten. 1: public void GetLocator() 2: { 3: var locatorSite = SharePointServiceLocator.GetCurrent(); 4: var locatorNoContext = SharePointServiceLocator.GetCurrent(new SPSite("http://intranet")); 5: var locatorFarm = SharePointServiceLocator.GetCurrentFarm(); 6: } Der erste Aufruf lädt den Locator mit den Mappings aus der aktuellen SPSite, dies funktioniert nur wenn ein SPContext zur Verfügung steht. Ist kein Kontext verfügbar (zb. in einer eigenständigen Anwendung welche auf SharePoint zugreift)., kann die Überladung mit Angabe einer SPSite verwendet werden. Der dritte Aufruf referenziert den Locator für die komplette Farm. Wird der Locator mit GetCurrent() referenziert, werden Mappings von der Farm und von der SiteCollectionebene geladen, wobei jene auf SiteCollection Ebene die entsprechenden Farm-weiten Mappings ersetzen. Mappings definieren 1: public void CreateFarmMappings() 2: { 3: var serviceLocator = SharePointServiceLocator.GetCurrent(); 4: var typeMappings = 5: serviceLocator.GetInstance<IServiceLocatorConfig>(); 6:  7: typeMappings.RegisterTypeMapping<IShippingCostService, ShippingCostCalculator>(); 8: } Um Mappings auf Farm Ebene zu definieren, muss zuerst der aktuelle Locator referenziert werden. Danach wird die Konfiguration des Locators geholt. Diese ist standardmässig ebenfalls als Service bereits im Locator registriert. Mittels RegisterTypeMapping wird nun ein Mapping definiert. Im Beispiel wird das IShippingCostService von ShippingCostCalculator implementiert. Um Mappings auf SiteCollection Ebene zu definieren muss lediglich die Site mit angegeben werden. 1:  2: public void CreateSiteMappings() 3: { 4: var serviceLocator = SharePointServiceLocator.GetCurrent(); 5: var typeMappings = 6: serviceLocator.GetInstance<IServiceLocatorConfig>(); 7: //Site angeben 8: typeMappings.Site = SPContext.Current.Site 9:  10: typeMappings.RegisterTypeMapping<IShippingCostService, ShippingCostCalculator>(); 11: } Damit ist die Konfiguration abgeschlossen. Ein guter Ort diese Konfiguration auszuführen ist ein FeatureEventReceiver, welcher beim Installieren die Konfiguration erzeugt. Wenn man sich eine klassische Anwendung welche auf SharePoint aufbaut vorstellt, wird aus dem Beispiel klar, wie der Locator eine Entkopplung erreicht und somit auch das automatisierte Testen ermöglicht. Angenommen der ShippingCostCalculator greift in seiner Implementierung auf eine SharePoint Liste zu zum Errechnen der Kosten. Automatisiertes Testen fällt somit aus – niemand wird auf dem Build Server einen SharePoint Server installieren. Ausserdem müsste zum Testen jedesmal die SharePoint Liste in einen genau definierten Zustand versetzt werden und nach dem Test muss wieder aufgeräumt werden. Geht man wie oben vor, kann man zum Testen ganz einfach eine Mock Implementierung von IShippingCostService im Locator registrieren, welche gefakte Werte liefert und somit ist die Abhängigkeit auf das externe System – SharePoint – verschwunden. Viel Spass beim Testen! Downloads: SharePoint 2010 Guidance Library   Andreas Aschauer

Real-World SharePoint Entwicklung: Logging mit der SharePoint Guidance Library

Von Andreas Aschauer Autor Feed 30. October 2010 12:21
Im Ankündigungspost für die SharePoint 2010 Guidance Library habe ich die verschiedenen fertigen Komponenent, welche die Bibliothek dem SharePoint Entwickler bietet schon angesprochen. Nun ist es an der Zeit, die Dinge genauer zu betrachten. Als erstes ist  der neue SharePoint Logger an der Reihe. Mit der Logging Komponente kann sehr einfach in die ULS Logs (im 14 ‘Hive’), wie auch in die Windows Event Logs von SharePoint geschrieben werden. Eine RIESEN Erleichterung, da bisher zum schreiben von Trace Informationen, sehr viel, sehr aufwendiger Code notwendig war. Warum wollen wir überhaupt ins ULS Log schreiben? Ein klassisches Entwicklungsszenario: Man entwickelt, eine tolle Solution auf der eigenen Virtuellen Maschine, auf der alles perfekt konfiguriert ist, dann wird das Paket zum Kunden ausgerollt und plötzlich geht nichts mehr. Debuggen ist nicht möglich auf den Servern des Kunden. Das klassische – Works on my machine Szenario! Und welcher SharePoint Developer kennt das nicht – der möge ein Kommentar hinterlassen Ein kleines Beispiel soll zeigen, wie einfach Logging nun ist. Gestartet wird mit dem Download der SharePoint Guidance Library. Nach dem Entpacken befindet sich im Verzeichnis Source, der komplette Quellcode, welcher in die eigenen Lösungen integriert werden kann. Dieser muss nur kompiliert werden. Zwei Assemblies sind notwendig, damit man die Funktionen der Library nutzen kann: Microsoft.Practices.SharePoint.Common.dll Microsoft.Practices.ServiceLocation.dll Nachdem die Assemblies erzeugt sind, erstellen wir unser neues Beispielprojekt – eine leere SharePoint Solution, dieser Solution fügen wir Referenzen auf die beiden obigen Assemblies hinzu. Als nächstes wird ein Element vom Typ “EventReceiver” eingefügt. Dieser Receiver wird unsere Testklasse zum Loggen enthalten. Abbildung 1: Einfügen eines neuen EventReceivers Los gehts mit dem Code: Folgende using Direktiven werden benötigt 1: using Microsoft.Practices.SharePoint.Common; 2: using Microsoft.Practices.ServiceLocation; Im EventReceiver wird das Ereignis “ItemAdded” behandelt, welches feuert, nachdem in der zugewiesenen Liste ein Eintrag erfolgt ist. Zunächst erzeugen wir uns einen neuen Logger. Dies geschieht nicht direkt mittels dem “new” Keyword, sondern gleich mit dem ServiceLocator, welcher ebenfalls Teil der Library ist. Der ServiceLocator wird im nächsten Artikel genauer beleuchtet. 1: //Aktueller Locator der SiteCollection 2: var serviceLocator = SharePointServiceLocator.GetCurrent(); 3: //Implementierung von ILogger holen 4: logger = serviceLocator.GetInstance<ILogger>(); Der SharePointLogger bietet zwei Methoden an, welche Logging bzw. Tracing ermöglichen. LogToOperations(..) und LogToDeveloper(..). Operations bezeichnet hier das Schreiben ins Windows Event Log und Developer das Tracing ins SharePoint ULS Log. Unser kleines Beispiel sieht wie folgt aus. 1: public override void ItemAdded(SPItemEventProperties properties) 2: { 3: ILogger logger = null; 4: var area = "Custom EventReceivers"; 5: var category = "Execution"; 6: var areaCategory = string.Format("{0}/{1}", area, category); 7:  8: try 9: { 10: base.ItemAdded(properties); 11: //Aktueller Locator der SiteCollection 12: var serviceLocator = SharePointServiceLocator.GetCurrent(); 13: //Implementierung von ILogger holen 14: logger = serviceLocator.GetInstance<ILogger>(); 15: //Test: Auslösen einer Exception 16: if (properties.ListItem.Title == "Error") 17: throw new Exception("The list item title told me to raise an exception"); 18:  19: SPSecurity.RunWithElevatedPrivileges(() => logger.LogToOperations( 20: string.Format( 21: "SpgTest.EventReceiver worked fine on {0}", 22: properties.ListTitle), 23: (int) EventId.Success, 24: EventSeverity.Verbose, 25: areaCategory)); 26:  27: } 28: catch (Exception ex) 29: { 30: //Exception in Trace schreiben (ULS Log) 31: if (logger != null) 32: logger.TraceToDeveloper(ex, "Error from SpgTest.EventReceiver", 33: (int)EventId.Error, 34: SandboxTraceSeverity.Unexpected, 35: areaCategory); 36: } 37: } Bei Erfolg, schreiben wir eine Nachricht ins Event Log, mit Severity Level “Verbose”. Wichtig ist immer eine Category und eine Area anzugeben, damit es den Administratoren, welche die Logs durchsuchen müssen leichter fällt, Nachrichten einzuschränken. Die Area und Category werden im Format Area/Category zusammengehängt. Schreibt man ins Windows Event Log entspricht die Area dem “Event Source Name” und die Category entspricht “Task Category”. Dasselbe gilt auch beim Tracing in die ULS Logs. Area und Category erleichtern das Suchen in den Textfiles ungemein. Ein weiterer wichtiger Punkt ist eine eindeutige EventId. Sie ermöglicht es zusammengehörige Ereignisse zu identifizieren. Hier bietet es sich immer an eine Enumartion zu erstellen, welche die verschiedenen IDs darstellt. 1: public enum EventId : int 2: { 3: Success, 4: Error, 5: Unknown 6: } Soweit ein kurzer Einblick in die spannenden Möglichkeiten der SharePoint Guidance Library. Im nächsten Artikel steht der neue Service Locator im Mittelpunkt – ein Muss für echte Softwareentwickler. Downloads: SharePoint 2010 Guidance Library   Andreas Aschauer Mail: andreas.aschauer@codeforce.at Twitter: www.twitter.com/CodeForceAT

Real-World SharePoint Entwicklung: Beispiele, Dokumentation und Bibliotheken für SharePoint 2010

Von Andreas Aschauer Autor Feed 29. October 2010 16:53
SharePoint Entwicklung ist mehr als nur das Anpassen von ein paar Seiten und Grundlegender Zugriff auf SharePoint Daten mittels API. Leider ist in der aktuellen Literatur von fortgeschrittenen Entwicklungsthemen nichts zu finden. Meist wird 300 Seiten erklärt was SharePoint ist und welche Möglichkeiten theoretisch existieren die Platform anzuprogrammieren und zu erweitern. Professionelle Entwicklerthemen wie Architekturen und Best-Practices etc. fehlen grundsätzlich gänzlich. Dich Abhilfe ist in Sicht: Microsoft hat sich dem Thema angenommen und der Tradition der “SharePoint Guidance Library” folgende, welche auch schon für SharePoint 2007 verfügbar war ein Paket zusammengestellt, dass neben einer eingehenden Dokumentation und “Echt-Welt” Entwicklungsbeispielen auch fertige Komponenten enthält, die jeder ernsthaft arbeitende SharePoint Entwickler braucht. So findet man in der Library eine SharePoint Logging Komponente, welche es einfach macht, ins Event Log oder auch in das ULS Log zu schreiben. Wer schon mal ins ULS Log selbst geschrieben hat, wird diese Logging Komponente lieben. Ganz wichtig aus meiner Sicht: Eine Implementierung eines Service Locators ist ebenfalls enthalten! Dieser ermöglicht es mittels eines Dependency-Injection Containers Abhängigkeiten zwischen Klassen dynamisch zur Laufzeit aufzulösen und erlaubt ein Austauschen von Implementierungen via Konfiguration. Tolle Sache ! – Nähere Informationen zu DI gibts in meine Artikel “Design Patterns: Teil 2 – Dependency Injection” und “”Design Patterns: Teil 1 – Inversion of Control & Dependency Injection. Im Microsoft Download Center kann “Developing Application for SharePoint 2010” geladen werden. Viel Spass mit der Professionellen Entwicklung auf der SharePoint Platform!   Andreas Aschauer Mail: andreas.aschauer@codeforce.at Twitter: www.twitter.com/CodeForceAT

SharePoint 2010: Forms Authentifizierung für SharePoint Anwendungen

Von Andreas Aschauer Autor Feed 1. October 2010 20:49
Es kann aus vielen Gründen praktisch oder erforderlich sein, SharePoint Anwendungen auf Forms Authentifizierung umzustellen. Entweder existiert kein Active Directory im Unternehmen oder man muss ein komplett eigenes Authentifizierungssystem anbinden, oder SharePoint soll in einer Art “Sandbox” Betrieb innerhalb eines Teams oder einer Abteilung getestet werden und es ist “Out-of-Scope” die bestehende AD Infrastruktur zu nutzen und anzupassen. Durchsucht man das Internet nach den Begriffen “SharePoint Forms-Based Authentication” und ähnlichem landet man sehr viele Treffer. Leider sind viele Tutorials entweder einfach falsch oder unnötig kompliziert. Deshalb soll hier so kurz wie möglich erklärt werden, wie man eine SharePoint Anwendung mittels ASP.NET SQL-Membership Provider auf Forms-Basierte Authentifizerung oder einen Mischbetrieb Forms/AD umstellt. Los gehts mit dem Erstellen einer SQL Server Datenbank welche die User und Profile enthält. Wie aus ASP.NET bekannt wird dies mit dem Tool “aspnet_regsql” erledigt. Dazu wird die Visual Studio Command Prompt gestartet und aspnet_regsql.exe aufgerufen. Wird das Tool ohne Parameter gestartet bekommt man einen grafischen Wizard präsentiert der das Anlegen der User Datenbank erledigt. Hier wird die Option “Configure SQL Server for application Services” gewählt und danach noch der Datenbankserver und optional der Name der DB angegeben. Abbildung 1 – Das Tool aspnet_regsql.exe Ist die Datenbank angelegt wird die SharePoint Anwendung erzeugt. In der Central Administration wird im Application Management eine neue Anwendung angelegt. Wichtig hierbei sofort: Den Authentifizierungsmodus auf “Claims Based” einstellen (siehe Abb.2) Abbildung 2 – Claims Based Authentifizierung aktivieren Wählt man den Claims Based Modus, hat man nachfolgend die Möglichkeit den Membership und Role Provider zu wählen. Wie in Abbilung 3 ersichtlich. Wichtig: Die Namen für den Membershipprovider und den Role Provider müssen mit den Namen so wie sie später in die web.config Datei wandern übereinstimmen. Im Beispiel heissen die beiden Komponenten: Sql-Membership bzw. Sql-Role. Abbildung 3: Namen des Membership/Role Providers angeben Ebenfalls wichtig. Die Option “Enable Windows Authentication” sollte aktiviert bleiben, da man sich ansonst selbst aussperrt, BEVOR man irgendeinem User aus der SQL Server Userverwaltungsdatenbank Rechte geben kann. Wurde die Anwendung erstellt folgt der mühsamste Teil. Insgesamt müssen 3 web.config Dateien angepasst werden. Die Konfiguration der Central Administration, damit man den Usern aus der DB Rechte auf Applikationsebene erteilen kann, die Konfiguration des Secure Token Services und natürlich die eben erstellte Webanwendung. Um die entsprechenden web.config Dateien zu finden ist es am einfachsten im IIS Manager auf die entsprechende Site Rechts-Klicken und “Explore” wählen. - Anpassen der Central Administration Folgende Snippets in die web.config einfügen. Das erste Snippet direkt nach </configSections>. Der Name des DB Servers und der DB Name müssen natürlich entsprechend angepasst werden. Hier wird die Verbunding zur Authentifizierungsdatenbank erstellt 1: <connectionStrings> 2: <add connectionString="data source=.; 3: Integrated Security=SSPI;Initial Catalog=SqlAuthentication" name="FBAConnection" /> 4: </connectionStrings> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Das 2. Snippet in die Sektion <system.web>. Hier wird der Membership Provider und der Role Provider eingestellt. 1: <roleManager defaultProvider="AspNetWindowsTokenRoleProvider" enabled="true" cacheRolesInCookie="false"> 2: <providers> 3: <add connectionStringName="FBAConnection" applicationName="/" description="Stores and retrieves roles from SQL Server" name="SQL-RoleManager" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> 4: </providers> 5: </roleManager> 6: <membership defaultProvider="SQL-MembershipProvider"> 7: <providers> 8: <add connectionStringName="FBAConnection" passwordAttemptWindow="5" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" applicationName="/" requiresUniqueEmail="true" passwordFormat="Hashed" description="Stores and Retrieves membership data from SQL Server" name="SQL-MembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> 9: </providers> 10: </membership> - Anpassen der Secure Token Service Application Die Konfigurationsdatei findet man im IIS Manager unter “SharePoint WebServices”/”SecureTokenServiceApplication”. Hier sieht die web.config etwas anders aus.Folgendes Snippet komplett nach der Sektion <system.net> einfügen. 1: <connectionStrings> 2: <add connectionString="data source=.;Integrated Security=SSPI;Initial Catalog=SqlAuthentication" name="FBAConnection" /> 3: </connectionStrings> 4:  5: <system.web> 6: <roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false"> 7: <providers> 8: <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" /> 9: <add connectionStringName="FBAConnection" applicationName="/" description="Stores and retrieves roles from SQL Server" name="SQL-RoleManager" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> 10: </providers> 11: </roleManager> 12: <membership defaultProvider="i"> 13: <providers> 14: <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" /> 15: <add connectionStringName="FBAConnection" passwordAttemptWindow="5" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" applicationName="/" requiresUniqueEmail="true" passwordFormat="Hashed" description="Stores and Retrieves membership data from SQL Server" name="SQL-MembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> 16: </providers> 17: </membership> 18: </system.web> 19: configuration> Hier auch wieder die Werte im Connectionstring an den eigenen DB Server anpassen. - Anpassen der Webanwendung Die web.config der Anwendung wird genau gleich verändert, wie jene der Central Administration oben. Voilá – die Änderungen sind vollbracht. Einmal Server neu starten oder Application Pools recyclen und los gehts. Zunächst wird in der Central Administration der neuen Anwendung eine User Policy hinzugefügt. Hat man alles richtig gemacht, kann man hier schon User aus der SQL Server DB auswählen. Im Beispiel wird mittels “Add Users” der Zone (Default) die Gruppe “All SQL-Membership Users” mit der Policy “Full Control” hinzugefügt. Das bedeutet alle User aus dem externen Authentifizierungssystem haben alle Rechte auf der Webanwendung – in Produktivsystem eher nicht zu empfehlen, für Beispielzwecke aber exemplarisch in Ordnung. Ab jetzt kann mit Forms-Authentifizierung voll transparent in allen Site Collections, Sites und Listen der Anwendung gearbeitet werden. Gar nicht so schwer!   Andreas Aschauer Mail: andreas.aschauer@codeforce.at Twitter: www.twitter.com/CodeForceAT

18.10.-22.10.2010, Redmond, Symposium patterns & practices, Redmond

Von Petra Kleiber Autor Feed 3. August 2010 12:14
    The Microsoft patterns & practices Symposium is the event for software developers and architects to have engaging and meaningful discussions with the people creating the technologies and guidance aimed at addressing their scenarios. This 5-day event provides an environment to learn about and discuss a broad range of Microsoft development technologies and the opportunity to drill into the details with p&p and product team members and industry experts. Symposium Highlights · Keynote Sessions by Senior Microsoft Executives and Technical Industry Leaders including Jason Zander, Yousef Khalidi, and Charlie Kindel · 3 Developer Workshops on Enterprise Library, Prism and Windows Azure · 25 Thought-provoking sessions on Windows Phone 7, SharePoint, ASP.NET, Dependency Injection, Agile practices, and much more including patterns for how to apply these technologies in proven ways · Evening Networking Reception with entertainment, food and drinks · Symposium Party on Thursday Night at Lucky Strike Billiards in Bellevue · “Ask The Expert” Lunches and several Open Space sessions         Learn more about the Symposium on the web at patterns & practices Symposium @pnpsymposium #pnpsym Facebook      

SharePoint 2010 Best Practices Guide

Von Andreas Pollak Autor Feed 13. July 2010 12:19
Vor kurzem wurde die SharePoint 2010 Development Guidance vom Microsoft patterns & practices Team publiziert. Die SharePoint 2010 Development Guidance bietet technische Insights in den SharePoint Server 2010, und best practices für SharePoint-EntwicklerInnen und –ArchitektInnen. Interessierte haben auf der SharePoint 2010 Guidance Codeplex Seite die Möglichkeit Feedback zu geben und Änderungsinput zu liefern. Andreas Pollak Product Marketing Manager Developer & Designer Tools

Sharepoint 2010: Community Kit for Sharepoint 2010

Von Andreas Aschauer Autor Feed 27. June 2010 18:43
In Visual Studio 2010 ist Out-of-the-Box schon eine umfassende Sharepoint Unterstützung integriert. Vom Sharepoint Explorer bis zu den Sharepoint Projekt und Item Templates und natürlich dem eingebauten Support zur Erstellung von WSP Paketen, wird dem Entwickler viel Arbeit und Suche nach exterenen Tools abgenommen. Über das neue Managed Extensibility Framework von Visual Studio 2010, können eigene Erweiterungen, Frameworks und Tool Chains einfach in die IDE integriert werden. Ein Projekt welches zum einen MEF nutzt und zum anderen die Sharepoint Entwicklungs Integration noch weiter treibt ist das Community Kit for Sharepoint – kurz CKSDev. CKSDev bringt eine Fülle neuer, sinvoller Features für die Sharepoint Entwicklung mit und integriert sich komplett transparent, in die bestehenden Sharepoint Tools. So wird zum Beispiel der Sharepoint Explorer ordentlich “aufgebohrt” und auch fehlende Item Templates, wie “Custom Action” gehören zum Umfang. Besonders praktisch ist “Get SPMetal Definition”. Dieses Feature fügt Listen und Seiten einen Menüpunkt hinzu, der es erlaubt mit einem Klick eine SPMetal Definition für LINQ2Sharepoint Projekte zu erstellen. Alle Details und den Download findet man auf CodePlex.

SharePoint 2010 Training Links

Von Andreas Pollak Autor Feed 22. June 2010 09:40
Hier noch ein paar ergänzende SharePoint 2010 Trainings Links: Sharepoint 2010 Developer Training Kit SharePoint 2010 Advanced Training Videos Developer Roadmap and Tools Core Development User Interfaces and Lists Data Access in Technologies Composite Solutions Enterprise Content Management Enterprise Search Business Intelligence Communities Development Life Cycle Channel 9 - Videos zu Sharepoint 2010 (siehe auch Sharepoint 2010: Teil 1 – Überblick über Sharepoint Produkte und Technologien) Andreas Pollak Product Marketing Manager Developer & Designer Tools

Sharepoint 2010: Teil 7 – Entwickeln mit Sharepoint

Von Andreas Aschauer Autor Feed 17. June 2010 15:45
Es ist an der Zeit in unsere Artikelserie endlich “richtig” mit Sharepoint 2010 zu arbeiten, für einen Softwareentwickler kann das nur eins bedeuten –> Code – in Form der Sharepoint API. Anhand der Umsetzung eines kleinen (Echt-Welt) Beispiels, sehen wir uns die Visual Studio 2010 Umgebung für Sharepoint an, die Feature/Solution Infrastruktur von Sharepoint sowie die API selbst. Die Anforderung sieht folgendermassen aus: Eine Sharepoint Liste wird via Import aus einem externen System mit E-Mail Adressen befüllt. Wird nun ein Element in der Liste verändert soll an die entsprechende E-Mail Adresse eine Nachricht versandt werden. Findige Leser werden einwerfen- “Dass geht Out-of-the-Box” – stimmt! ABER: Diese Anforderung stammt aus einem echten Projekt und wie immer liegt der Teufel im Detail. Nur so viel sei gesagt, in diesem konkreten Fall gehts nicht mit Bordmittel – daher ergibt sich daraus ein nettes kleines Programmierbeispiel für Blogs etc. :-) Umgesetzt wird die Anforderung mit der Sharepoint Objektmodell mit einem “Event Receiver”. Sharepoint bietet eine grosse Anzahl an “Event Receiver” an. Kurz gesagt ermöglichen sie, das “Reagieren” auf bestimmte Ereignisse in der Sharepoint Infrastruktur. Umgesetzt wird ein EventReceiver ganz einfach als Assembly, welche in den GAC wandert. Los gehts – Wir legen in Visual Studio 2010 ein neues Projekt vom Typ “Sharepoint 2010 – Event Receiver” an. Diese Vorlage und der folgende Wizard erledigen viele Konfigurationsaufgaben für uns, die mit Sharepoint 2007 noch alle händisch zu tätigen waren, wir müssen uns nur mehr auf unsere Business Logik konzentrieren. Im Wizard, der erscheint sobald man auf “Weiter” klickt, lassen wir eine “Sandboxed-Solution” erstellen, das heisst wir können ausserhalb unserer SiteCollection nichts “anstellen” mit unserem eigenen Code. Wichig ist die nächste Seite, hier wird eingestellt auf welche Listenvorlagen der EventReceiver reagieren soll und auf welches Ereignis. Es gibt grundsätzlich 5 Gruppen von Ereignissen: Listenereignisse, Listenelementereignisse, Webereignisse, Workflow- und Emailereignisse. Fürs Beispiel wählen wir Listelementereignisse (List Item Events) und das Ereignis “An item was updated” –> Wir reagieren also NACHDEM ein Element geändert wurde. Das Ereignis “An item is being updated” wäre das Pendant dazu, BEVOR ein Update passiert. Als Ereignisquelle wählen wir im Beispiel “Custom List”, also Benutzerdefinierte Liste. Hier würde in einem realen Projekt noch granularer eingeschränkt auf “Task” etc. Ein Klick auf “Finish” erzeugt alle notwendigen Konfigurationsdateien, damit unsere Solution sofort auf Knopfdruck “Deployed” werden kann – dazu am Ende des Artikels mehr. Ist die Erzeugung der Solution fertig, wird im Code Editor sofort die Klasse EventReceiver1 angezeigt. Diese Klasse leitet von SPItemEventReceiver ab und stellt alle benötigten EventHandler bereit um auf die Sharepoint Ereignisse zu reagieren. Weiters ist der EventHandler ItemUpdated sofort erzeugt worden. Wir brauchen nur mehr “ausfüllen” mit unserer Businesslogik. 1: public class EventReceiver1 : SPItemEventReceiver 2: { 3: public override void ItemUpdated(SPItemEventProperties properties) 4: { 5: base.ItemUpdated(properties); 6: } 7: } Drei Dinge müssen passieren, damit unsere Spezifikation umgesetzt wird. - Auslesen der E-Mail Einstellungen - Auslesen der E-Mail Adresse aus dem Listenelement - Versenden der Email   Auslesen der E-Mail Einstellungen Die E-Mail Einstellungen sollen “von aussen” konfigurierbar an den EventReceiver übergeben werden. Dinge wie Absenderadresse, Subject und Text sollten nicht hardcoded werden. Dies kann einfach erreicht werden indem man die Eigenschaft “ReceiverData” von SPListeItemEventProperties verwendet. Mithilfe dieser Eigenschaft lassen sich beliebige Daten übergeben. Im Beispiel werden die Daten einfach in folgenden Format mit übergeben FROM:sharepoint@codeforce.at|Subject:TestMail|Body:This is a test! 1: public static EmailSettings GetEmailSettings(string eventData) 2: { 3: var sections = eventData.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries); 4: var settings = new EmailSettings 5: { 6: FromAdress = sections[0].Split(':')[1], 7: Body = sections[1].Split(':')[1], 8: Subject = sections[2].Split(':')[1], 9: EmailFieldName = sections[3].Split(':')[1] 10: }; 11: return settings; 12: } Und der Aufruf dazu: 1: var settings = GetEmailSettings(properties.ReceiverData); Im Beispiel wurde jegliche Fehlerbehandlung entfernt, die sollte natürlich nicht fehlen! Wie wir die Eigenschaft “ReceiverData” befüllen, sehen wir am Ende des Beispiels. Zugriff auf das Listenelement – Auslesen der Email Adresse Interessant wirds im 2. Punkt, hier müssen wir via Objektmodell auf Inhalte der Liste zugreifen. Auch keine Hexerei! 1: var address = properties.ListItem.GetFormattedValue(emailFieldName); Über das Argument “properties” der Methode “ItemUpdated” kommen wir einfach an des Listenelemnt, welches das Ereignis ausgelöst hat. Um nun ein gewisses Feld abzurufen bietet sich die Methode “GetFormattedValue()” an, da sie die Daten eines Feldes IMMER als formatierten string zurückliefert. Je nach Feldtyp kann das auch zu, nur mehr bedingt lesebaren Ausgaben führen – falls das Feld einen komplexen Typ wie “Lookup” oder “BusinessData” hat. Alternativ kann auch einfach der Indexer verwendet werden. 1: var address = properties.ListItem[emailFieldName]; Versand der E-Mail Am einfachsten gelingt dies mit einer Hilfsmethode aus der statischen Klasse SPUtility – die EMail wird dann nämllich sofort versandt und “umgeht” die Sharepoint “Immediate Alert” Architektur. Das hat den Vorteil, dass man beim Testen nicht immer warten muss, bis der Timer Dienst “Immediate Alerts” versendet. 1: public bool SendMail(EmailSettings settings,string toAdress, SPWeb web) 2: { 3: return SPUtility.SendEmail(web, false, false, toAdress, settings.Subject, settings.Body); 4: } Soweit ist unser Code damit fertig. Im Anhang findet sich die komplette Klasse. Wie wird nun unser EventReceiver in Sharepoint registriert? Im Visual Studio Projekt finden sich unter dem Punkt “Features” einige Dateien welche aus der Vorlage erzeugt wurden. Ein Feature in Sharepoint Terminologie ist die “Verpackungseinheit” für alle Dinge, die man ausrollen will in die Farm. Ein Feature besteht aus zwei oder mehr XML Dateien, die die Inhalte beschreiben. Visual Studio 2010 bietet für Features einen eigenen Designer, also ist es nicht mehr nötig das genaue XML Schema zu kennen. Öffnet man mit Doppelklick ein Feature sieht man dessen Inhalt – der EventReceiver in unserm Fall. Die ganze “Magie” – also die Zuordnung unseres Codes zu dem Sharepoint Event passiert in der Datei Elements.xml, die man mittels Kick direkt im Feature Designer öffnet (Ein Klick auf das kleine “ + Files “ lässt den Link zur Elements.xml erscheinen). 1: <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> 2:  3: <Receivers ListTemplateId="107"> 4: <Receiver> 5: <Name>List Mailer</Name> 6: <Type>ItemUpdated</Type> 7: <SequenceNumber>100</SequenceNumber> 8: <Assembly>TaskListFeatures, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7eaab9b475a29bf8</Assembly> 9: <Class>TaskListFeatures.Features.TaskMailer.TaskListMailerEventReceiver</Class> 10: <Data>From:sharepoint@codeforce.at|Body:Hello World!|Subject:Test Mail|FieldName:email Adress</Data> 11: <Filter> 12: </Filter> 13: </Receiver> 14: </Receivers> 15: </Elements> Hier im Element Manifest, sieht man die Zuordnung zur Liste. Das Element “Receivers” spezifiziert ein oder mehrere Receiver Klassen auf bestimmten Listenvorlagen. Es wird auf eine Assembly und eine Klasse verwiesen, die das Event verarbeitet. Wichtig ist hier auch die Sequence! Es kann sein, dass mehrere Receiver aufs selbe Event reagieren, mit der Sequence kann man sie in eine Reihenfolge bringen. Hier wird auch mit dem Element “Data” die Konfiguration gespeichert. Die Zeichenfolge in “Data” steht dann in der Eigenschaft ReceiverData, welche wir für die Email Einstellungen verwendet haben zu Verfügung. Soweit haben wir unseren Receiver fertig, mit Rechts-Klick im Solution Explorer kann das Ganze “Deployed” werden. Visual Studio 2010 verpackt dabei alle Features in eine Sharepoint Solution (ein CAB Archiv mit der Endung .wsp") und rollt diese am Server aus. Geschafft! Sobald nun in einer Liste vom Typ “Custom List” ein Element geändert wird, feuert unser EventReceiver! Mehr zur Feature/Solution Infrastruktur sehen wir uns im nächsten Artikel wieder Hands- On an.

SharePoint 2010 Prozess-Management und Workflows

Von Mario Meir-Huber Autor Feed 4. June 2010 22:09
SharePoint 2010 bietet enorme Verbesserungen im Vergleich zu MOSS 2007, auch im Bereich Prozess-Management und Workflows. Abhängig von den konkreten Anforderungen haben aber nach wie vor 3rd-Party Produkte wir Nintex oder K2 eine große Existenz-Berechtigung. Im Rahmen der SharePoint Konferenz in Wien ist auch der im .net-Bereich führende Enterprise-Workflow-Anbieter K2 am 9. und 10. Juni zu Besuch. Gemeinsam mit smartpoint werden dabei in einem kompakten Business-Briefing erstmalig in Österreich die K2-Neuerungen für SharePoint 2010 vorgestellt. Dieser Vortrag findet am Ende des ersten SharePoint-Konferenz-Tages (9. Juni) zw. 17:45 und 18:45 Uhr im Hotel Savoyen statt – es ist perfekt eingebettet zwischen den letzten Vorträgen sowie dem Abendprogramm. Agenda: 17:45 - 18:00 Begrüßung und Einleitung Michael Pachlatko, smartpoint & Kevin Eley, K2 18:00 - 18:30 K2 Workflow: Extra Value for SharePoint 2010 (Vortrag auf Englisch) Kevin Eley, K2 & Nicholas Kotze, K2 18:30 - 18:45 K2 Enterprise Workflow & SharePoint im Einsatz bei Gebauer & Griller Markus Kasteiner, Gebauer & Griller Ort: Austria Trend Hotel Savoyen Vienna, Rennweg 16, 1030 Wien Die Teilnahme ist kostenlos und nicht an eine SharePoint-Konferenz-Teilnahme gebunden, die Teilnehmeranzahl ist allerdings begrenzt. - Wir freuen uns auf Ihre Anmeldung! Für Details und Anmeldung klicken Sie bitte auf http://www.smartpoint.at/events.htm

Sharepoint 2010: Teil 6 – Silverlight in Sharepoint 2010

Von Andreas Aschauer Autor Feed 28. May 2010 18:27
Nachdem wir in den vorangegangen Teilen der Artikelreihe viel pber administrative Funktionen und die grundlegenden Konzepte von Sharepoint Out-of-the-Box zu erfahren war, wenden wir uns jetzt einem “coolen” Entwicklerthema zu – Silverlight mit Sharepoint 2010. Das heisst: Eine schöne UI wie man sie von einer modernen RIA erwarten darf, aufbauend auf die Enterprise Plattform Sharepoint. Klingt gut - Also gleich mitten rein! Unsere Aufgabe: Für ein Project Management Office soll in Sharepoint grafisch ausgewertet werden, welcher Mitarbeiter wie stark (in Stunden) in ein Projekt involviert war/ist. Zunächst legen wir ein neues Silverlight Projekt an und referenzieren das Sharepoint Client Object Model, welches es uns erlaubt, typisiert auf Sharepoint, vom Client aus, zuzugreifen. Vor Sharepoint 2010 konnte man nur via SOAP WebServices remote auf Sharepoint zugreifen. Das ist Geschichte: In der aktuellen Version steht das Client OM zur Verfügung und sogar ein REST basierter Zugriff. Nähere Informationen dazu, in den Links. Das Client OM für Silverlight ist definiert in den Asssemblies Microsoft.Sharepoint.Client.Silverlight und Microsoft.Sharepoint.Client.Silverlight.Runtime welche sich im 14 Hive unter \TEMPLATE\LAYOUTS\ClientBin befinden. Da Sharepoint 2010 Silverlight 3 verwendet, befinden sich die Chart Controls im Silverlight 3 Toolkit, welches extra geladen werden muss und unter “Downloads” unten verlinkt ist. Nach der Instalaltion des Toolkits steht unter Add Reference > .NET > Die Komponente System.Windows.Controls.DataVisualization.Toolkit zur Verfügung, die ebenfalls referenziert werden muss. Als nächstes öffnen wir den Code unserer App.xaml und fügen in die Application_Startup Methode den Initialisierungsaufruf für das Client OM hinzu. 1: using Microsoft.SharePoint.Client; 2: using System.Threading; 3: .. 4: private void Application_Startup(object sender, StartupEventArgs e) 5: { 6: .. 7: ApplicationContext.Init(e.InitParams, SynchronizationContext.Current) 8: .. 9: } Danach erstellen wir in MainPage.xaml unser Chart. Zunächst binden wir in der XAML Ansicht den passenden XML Namepace ein und dann definieren wir unser Chart. Hier erzeugen wir ein Balkendiagramm das die Properties Contributions als y-Achsenwert und Name als x – Achsenwert nimmt. Die Properties werden wir in einem eigenen ViewModel noch deklarieren. Ist alles richtig erscheint das Chart sofort im Designer. 1: xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting; 2: assembly=System.Windows.Controls.DataVisualization.Toolkit" 1: <chartingToolkit:Chart x:Name="empContribChart" Width="450" 2: Height="300" Title="Employee Contributions / Project"> 3:  4: <chartingToolkit:Chart.Series> 5:  6: <chartingToolkit:ColumnSeries ItemsSource="{Binding}" 7: DependentValuePath="Contributions" 8: IndependentValuePath="Name" 9: AnimationSequence="FirstToLast" 10: Title="Contributions / Employee" 11: IsSelectionEnabled="True" /> 12:  13: </chartingToolkit:Chart.Series> 14: </chartingToolkit:Chart> Als nächstes definieren wir uns ViewModel, welches wir dann an das Chart binden. Es wird eine neue Klasse EmployeeContribution eingefügt, welche die zwei Chart Properties enthält. 1: public class EmployeeContributions 2: { 3: public string Employee { get; set; } 4: public decimal Contribution { get; set; } 5: } 6: Dann fügen wir im Code unserer MainPage die Methoden hinzu welche asynchron via Client OM die Daten von Sharepoint Server abrufen. Die Methode LoadData() wird vom Konstruktor aus aufgerufen. Die Vorgehensweise ist etwas gewöhnungsbedürftig. zunächst wird ein ClientContext angelegt. Jedes Objekt muss danach explizit mit Load() geladen werden. So laden wir das Web und die eigentliche Sharepointliste “EmployeeContributions”. Sobald der Aufruf ExecuteQueryAsync() erfolgt, werden die Anfragen asynchron an den Server gesandt und ausgeführt. In unserem EventHandler OnRequestSuceeded binden wir anschliessen die Daten. Achtung! Das der asynchrone Aufruf nicht im UI Thread stattfindet muss hier Dispatcher.BeginInvoke(..) verwendet werden! 1: private void LoadData() 2: { 3: ClientContext context = new ClientContext(ApplicationContext.Current.Url); 4: context.Load(context.Web); 5: List employees = context.Web.Lists.GetByTitle("EmployeeContribution"); 6: context.Load(employees); 7: 8: _employees = employees.GetItems(new CamlQuery{ViewXml=""}); 9: context.Load(_employees); 10: context.ExecuteQueryAsync(new 11: ClientRequestSucceededEventHandler(OnRequestSucceeded), null); 12: } 13: 14: private void OnRequestSucceeded(Object sender, ClientRequestSucceededEventArgs e) 15: { 16: Dispatcher.BeginInvoke(BindData); 17: } Zum Schluss implementieren wir noch BindData(), diese Methode durchläut die _employess Variable (die Sharepoint Liste) und erzeugt eine generische Liste von EmployeeContribution Instanzen. Zum Schluss wird noch nach Project gruppiert und die Werte für Contribution pro Mitarbeiter aufsummiert. 1: private void BindData() 2: { 3: var viewModelList = new List<EmployeeContribution>(); 4:  5: foreach (ListItem item in _employees) 6: { 7: viewModelList.Add(new EmployeeContribution 8: { 9: Employee = item["Title"].ToString(), 10: Contribution = Convert.ToDecimal(item["Contribution"]), 11: Project = item["Project"].ToString() 12: }); 13: } 14:  15: var totalContrib = viewModelList.GroupBy(emp => emp.Project).Select(c => new EmployeeContribution 16: { 17: Employee = c.Key, 18: Contribution = c.Sum(emp => emp.Contribution) 19: }).ToList(); 20:  21: empContribChart.DataContext = totalContrib; 22: } Anschliessend komplieren wird das Project und kopieren die *.XAP Datei in den 14 Hive nach \TEMPLATE\LAYOUTS\ClientBin. Danach erstellen wir auf einer Seite unserer Wahl ein neues Silverlight WebPart und geben in der Konfiguration des WebParts den Pfad zur XAP Datei an ( /_layouts/ClientBin/[Nme der XAP] ) ..fertig! So einfach wird mit Silverlight und dem Client Object Model aus einfachen Listendaten ein auf Wunsch animierter, interaktiver Graph. Ein Tipp noch: Falls SecurityExceptions auftreten, liegt das an einer fehlenden clientaccesspolicy.xml –> Silverlight 3 – Sharepoint Cross Domain Calls Links Sharepoint Foundation REST Interface Sharepoint Client Object Model Silverlight 3 – Sharepoint Cross Domain Calls Downloads Silverlight 3 Toolkit

Entwickler Wettbewerbe:

Wettbewerbe

Entwickler Events:

Developer Events

App für Windows 8, Windows Phone oder/und Azure? Diese Events zeigen Dir, wie es geht:

Mehr Information

Aktuelle Downloads

Visual Studio Downloads
 
Windows Azure Free Trial
Instagram
CodeFest.at on Facebook

Datenschutz & Cookies · Nutzungsbedingungen · Impressum · Markenzeichen
© 2013 Microsoft. Alle Rechte vorbehalten · BlogEngine.NET 2.7.0.0 · Diese Website wird für Microsoft von atwork gehostet.
powered by atwork