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

Sharepoint 2010: Teil 5 – Grundlegende Konzepte von Sharepoint – Listen / Bibliotheken

Von Andreas Aschauer Autor Feed 10. May 2010 14:22
Unser Sharepoint Server sollte nach der Installation, Konfiguration und den ersten Einstellungen in der Zentraladministration fertig und frisch sein um damit loszuarbeiten. Aber wie startet man ? Im 5. Teil der Artikelreihe beschäftigen wir uns mit den grundlegenden Konzepten der Sharepoint Plattform, zur Verwaltung jeglicher Daten – Listen und Bibliotheken. Eine Liste ist die Basisstruktur in der sämtliche Daten von einfachen Einträgen in einem Kalender bis hin zu Infopath Formularen etc. abgelegt werden. Eine Liste kann man sich vereinfacht wie eine Tabelle in einem relationalen Datenbanksystem vorstellen – wobei Listen um ein Vielfaches flexibler sind! Listen wiederum bestehen aus Spalten – in Sharepoint Fields genannt – welche den Datentyp einer “Zelle” eines Eintrags vorgeben. Also zum Beispiel das Field “Vorname” vom Typ “Text”. Ein weiterer wichtiger Teil von Listen sind die Listenansichten (List Views). Sharepoint Listen bestehen insgesamt aus 3 “Modulen”: Das Listenschema (die Sammlung der Fields), die Listenansichten und die Listenformulare (zur Eingabe/Editieren/Ansicht eines Elements). Eine Bibliothek ist auch eine Liste, wobei jedes Element einer Bibliothek aus einer Datei (zB Dokument) bestehen muss optional zusätliche Felder haben kann. Zum Anlegen einer neuen Liste muss man nur auf der Site seiner Wahl unter den “Site Actions” auf “More Options..” klicken, dann erscheint ein hübscher Dialog (umgesetzt mit Silverlight und der neuen Dialog API von Sharepoint 2010) . Alternativ kann man auch einfach auf “Lists” in der Aktuellen Navigation (links) klicken und dann auf “Create”. Siehe Abb. 1 Abb. 1 - “Create” Dialog Sharepoint bietet eine Reihe von Listenvorlagen, welche sich einfach durch ihre Spalten und Listenansichten unterscheiden. Eine Taskliste zum Beispiel enthält Spalten welche angeben wer für einen Task verantwortlich ist und wie lange ein Task dauert etc. und ebenfalls passende Ansichten (My Tasks). Alle diese Listenvorlagen basieren auf der Basislistenvorlage “Custom List”. Wir wählen Custom List aus und vergeben für unsere neue Liste einen Namen. Anschliesend kommt man in die Standardansicht der Listen, von hier aus werden alle Einstellungen über das neue Ribbon oben vorgenommen. Abb. 2 – List Ribbon Erster Anlaufpunkt zur Gestaltung des Listenschemas, also zur Erzeugung von Spalten sind die “List Settings” rechts im Ribbon. Auf dieser Seite lassen sich mit den entsprechenden Menüpunkten alle Einstellungen verwalten. Alles von Titel und Beschreibung der Liste bis hin zu den Email und Versionierungseinstellungen kann hier getroffen werden. Mittels “Add Column” kann nun ein Field eingefügt werden. Abb. 3 – Neues Field In Abbildung 3 sieht man welche Eigenschaften ein einzelnes Feld eines Listenschemas hat. Man kann einen Namen vergeben und den passenden Datentyp wählen. Via Sharepoint API kann natürlich die Liste vorgegener Datentypen erweitert werden. Stichwort : Custom Fields Ein Nachteil wenn man Felder direkt in Listen einfügt ist die fehlende Wiederverwendbarkeit. Definiert man ein Mitarbeiterverzeichnis mit allen Spalten und möchte dieses Schema ein zweites mal für eine weitere Liste verwenden, so muss man von vorne beginnen. Um hier Abhilfe zu schaffen gibt es Content Types (Inhaltstypen). Sie werden in den Site Settings unter “Galleries” / “Content Types” erstellt und sind Container für eine Sammlung von Spalten. Einen Content Type kann man nachdem er erstellt wurde dann jeder Liste zuweisen. Wird der Content Type verändert kann man die Änderungen nach unten “propagieren”. So kann man die Datendefinitionen zentral verwalten. Neu bei Sharepoint 2010 sind sogenannte Enterprise Content Types. Diese erlauben es Content Types in einer Site Collection – dem sogenannten Content Type Hub zu definieren und beliebige andere Site Collections können diese Content Types abonnieren. So wird es möglich für eine komplette Farm die Content Types zentral zu verwalten. Abschliessend seien noch folgende eingabaute Listenfeatures erwähnt: Man kann Email an Listen/Bibliotheken senden, der Inhalt wird in Sharepoint abgelegt Listen / Bibliotheken sind auf Wunsch Versioniert und erfordern eine Inhaltsgenehmigung Workflows können auf Listen und auch auf Content Types gebunden werden Listen können auf Knopfdruck als RSS Feed abonniert werden Man kann Bibliotheken via WebDAV im Explorer darstellen und Dokumente via Drag & Drop hochladen. Listen und Bibliotheken sind auf Knopfdruck nach Excel exportierbar Listen und Bibliotheken lassen sich mit den eingebauten Sharepoint Webparts sehr einfach auf beliebigen Seiten darstellen. Abb. 4 – Listen WebParts Klickt man auf “Edit Page” und “Insert” / “Existing List” so kann jede existierende Liste ganz einfach auf einer Seite dargestellt werden. Öffnet man eine Liste mit dem Sharepoint Designer (im Ribbon der Liste verfügbar), kann man die ASPX Seiten, welche zur Eingabe, Anzeige und zum Editieren der Listenelemente verwendet werden einfach anpassen (unter “Forms). Jede Liste ist übernimmt die Berechtigungen ihrer Site. Natürlich kann jede Liste und auch jedes Element einzeln berechtigt werden. Soweit eine ganz kurze Einführung in die schier unendlichen Möglichkeiten die Sharepoint mit dem Listenkonzept bietet. Viel Spass beim Experimentieren – hoffentlich nicht auf Produktivsystemen.

Sharepoint 2010: Teil 4 - Administration von Sharepoint Server 2010

Von Andreas Aschauer Autor Feed 29. April 2010 16:40
Nachdem unsere Sharepoint Installation und Erstkonfiguration abgeschlossen sein sollte, startet die Weboberfläche und präsentiert die neue Central Administration. Hier fällt gleich zu Beginn auf, dass sich ein Konfigurationswizard startet, der anbietet alle Schritte zur Erstellung eines Portals zu erledigen. Die Idee eines Wizards is gut, wir machen das Ganze jedoch händisch :-) damit wir 1.) den Prozess kennenlernen und 2.) flexibel sind und alle Einstellungen selber festlegen können. Abb. 1 – Sharepoint Farm Configuration Wizard Erstellung eines Intranet Portals Wir wollen ein neues Top-Level Portal zum Einstieg in ein Intranet erstellen – was brauchen wir dazu? 1.) Eine (ASP.NET) Web-Anwendung, die das Portal hosted.  2.) Einen dedizierten Application Pool, damit unser Intranet unabhängig verwaltet werden kann 3.) Eine Site-Collection. Eine Site Collection in Sharepoint stellt einen Container für eine Sammlung von Sites dar. Also unser Top-Level Portal unter dem dann verschiedenste Abteilungssites etc. angelegt werden. - Webanwendung erstellen Beginnen wir mit dem Erstellen der Webanwendung. In der Sharepoint Central Administration findet sich der Punkt “Application Management”, dahinter verbirgt sich eine Liste von Webanwendungen. Im Ribbon oben befindet sich eine “New” Button, über diesen kommt man zum Erstellungsdialog. Diese dialog-artigen Seiten sind übrigens eine neues Feature von Sharepoint 2010. Abb. 2 – Endpunkt der Webanwendung Einige Angaben sind nötig, für die neue Anwendung. Die wichtigsten Punkte sind: Wir erstellen eine neue IIS Website (“Create new IIS web site”) damit unsere Anwendung sauber vom Rest der Sites am IIS getrennt ist. Unter “Port” und “Host Header” haben wir die Möglichkeit, den “Endpunkt” zu definieren über den die Anwendung erreichbar ist. Bei Webanwendungen, welche von End-Usern bedient werden, bietet es sich immer an den Standard-Port 80 zu verwenden, da kein User gewohnt ist den Port (abc.com:82) an die URL anzuhängen. Um unsere Webanwendungen alle auf Port 80 betreiben zu können, werden sie über “Host Header” unterschieden. In Abbildung 2 oben sieht man den Host Header (portal.development.local). Damit diese URL erreichbar ist muss man natürlich auch einen entsprechenden DNS Eintrag erzeugen oder erzeugen lassen!   Abb. 3 – Application Pool und Content Datenbank erzeugen Ein weiterer wichtiger Punkt bei der Erstellung ist die Auswahl oder Erzeugung eines Application Pools. Man sollte bei der Planung für Sharepoint darauf achten, alle Webanwendunge sauber administrativ zu trennen. Liegen 2 Anwendungen im selben Application Pool, ist es nicht möglich sie getrennt zu “resetten” –> und das Zurücksetzen ist eine häufige Tätigkeit bei Sharepoint Entwicklung. Wenn zB. das Intranet und ein Kundenportal im selben Application Pool liegen, kann es sehr unangenehm für die Kunden sein, wenn der Application Pool “recycled” wird; alle Session enden dann nämlich abrupt! Im Beispiel legen wir einen neuen Application Pool für die Anwendung an und geben den Service Account, den wir für Sharepoint erstellt haben als Dienstkonto für den Application Pool an. Danach wird noch der Datenbankserver und der Name der Inhaltsdatenbank angegeben. Wichtig hierbei: Sprechende Namen für die Datenbank! Der DB Admin wirds beim Backup danken, wenn einfach ersichtlich ist welche Webanwendung welche Datenbank verwendet. Dienstanwendungen verbinden Bis zu Version 2007 von Sharepoint Server wurden farm-weite Dienst von einem oder mehreren Shared-Services-Provider angeboten. Diese Dienste umfassten Excel Services, Suche, Index, uvm. Das Problem mit SSP’s war das jede Webanwendunge mit genau einem Provider verbunden war und alle Dienste konsumieren musste. Das führte dazu, dass man mehrere SSP’s anlegte mit verschienden Diensten und Einstellungen – ein administrativer Overhead. Die Service Applications in Sharepoint 2010 lösen dieses Problem. Die Architektur wurde flexibler gestaltet. Die Dienste laufen auf einem Server und Webanwendungen “abonnieren” Dienste, welche für sie relevant sind. Diese “Service Associations” sind in der Central Administration zu verwalten und man kann sie einzeln parametrisieren, sodass jede Anwendung genau nur die passenden Dienste mit den passenden Einstellungen konsumiert.   Abb. 4 – Dienstezuordnungen für die Webanwendung erstellen - Site Collection erstellen Nachdem die Webanwendung erzeugt wurde, ist sie über ihre URL erreichbar, aber natürlich “leer”. Also ist es an der Zeit Inhalte zu erzeugen. Abb. 5 – Erstellen einer Sitecollection In der Central Administration unter “Create Sitecollection” erzeugen wir uns eine neue Site Collection. Die Site Collection stellt das oberste Elemen in einer Sharepoint Hierarchie dar. Sie ist der “Container” für die darunterliegenden Websites und ermöglich das gemeinsame Administrieren einer Gruppe zusammengehöriger Sites (zB Abteilungen). Weiters können somit Inhalte und Vorlagen erstellt werden, die für alle darunterliegenden Websites verfügbar sind. Siehe Abb. 6 Abb.6 – Sharepoint Site Hierarchie Zum Erzeugen der Site Collection geben wir einen Titel an und einen Pfad unter dem sie verfügbar ist. Normalerweise beim Portal auf oberster Ebene ist das die Root-URL der Webanwendung - also zB. portal.development.local. Es ist aber auch möglich mit “Managed Paths” Pfade anzugeben sodass nicht nur eine sondern viele Site Collections unter einem gemeinsamen Root laufen können zB. portal.development.local/sites/[PORTAL] . Nähere Informationen zu Managed Paths und wann man sie verwenden sollte finden sich in der “Links” Sektion am Ende des Artikels. Wir wählen als Vorlage das “Publishing Portal”. Diese Vorlage ist ganz gut für ein Intranet geeignet das sie via Sharepoint Publishing Feature eine Art Web-Content-Management System bietet. Das bedeutet dass User basierend auf vorgegebenen Templates eigenen Content erzeugen können – eine nette Motivation für die Benutzung des Intranets. Wichtig ist noch die 2 Site Collection Admins auszuwählen! Warum 2 ? Ein Punkt der oft übersehen wird, ist dass AD – Domain Admins NICHT automatisch Site Collections Admins in Sharepoint sind, sondern nur die 2 die man explizit angibt. Man sollte sich also gut überlegen wer zB. gleichzeitig mit wem auf Urlaub ist (sogar Admins machen gerüchteweise Urlaub). Damit ist die Einrichtung der Sitecollection abgeschlossen und nachdem alles erstellt wurde erstrahlt unser erstes Sharepoint Portal in vollem Glanz! Mehr zum Arbeiten mit Sites/Site Collections, Listen, Bibliotheken etc. gibts dann in Teil 5. Bis dahin – viel Spass beim Testen ! Links: Sharepoint Managed Paths Sharepoint Publishing Features

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