Enterprise Library Logging Application Block mit SharePoint 2010 nutzen

18.12.2011 | 20:03

Allgemein

Beim Erstellen von Software Anwendungen ist es wichtig, eine gute Logging Engine in die Software zu integrieren. Diese soll möglichst flexibel in der Konfiguration sein, um protokollierte Informationen in ein gewünschtes Ziel (Trace Listener) zu speichern. Hierfür eignet sich die Enterprise Library, diese enthält einen Logging Application Block, mit der sich per Konfiguration die Ausgabe ändern lässt. Als mögliche Ausgabe kann z.B. die Ereignisanzeige, Textdatei, E-Mail Nachricht oder eine Datenbank festgelegt werden, weitere Infos gibt es hier

Im folgendem werde ich beschreiben, wie man das Logging Application Block aus der Enterprise Libraray 5.0 in einer SharePoint 2010 Anwendung nutzt und das Deployment vorbereitet.

 

Einrichtung

Zuerst muss die Enterprise Library 5.0 heruntergeladen und installiert werden: Download

Anschließend wird eine leere SharePoint 2010 Solution erstellt

 

Zur Solution wird eine Application Page hinzugefügt, hier LoggingTest.aspx

 

 

Um die Logging Funktionalität nutzen zu können muss die folgende Assembly aus dem Enterprise Library Verzeichnis referenziert werden:

Microsoft.Practices.EnterpriseLibrary.Logging.dll

 

Jetzt muss noch die Web.config von SharePoint angepasst werden. Hierfür gibt es zwei Wege, manuell oder mit dem empfohlenem mitgelieferten Konfigurationstool EntLibConfig.exe
Im Konfigurationstool muss die jeweilige anzupassende Config Datei ausgewählt werden, in diesem Fall die Web.config, diese befindet sich im folgendem Pfad:

C:\inetpub\wwwroot\wss\VirtualDirectories\80

 

Anschließend können über das Menü Blocks weitere Settings hinzugefügt werden, hier Logging Settings.

 

Nach dem Hinzufügen wird die Web.config um Logging Funktionaltität erweitert. Als Standard wird als Ausgabe die Ereignisanzeige (Event Log) festgelegt, so das keine weiteren Anpassungen gemacht werden müssen.

 

 

Entwicklung

Jetzt kann die Logging Funktionalität in der LoggingTest.aspx genutzt werden. Hierfür wird die Klasse Logger aus den Namespace Microsoft.Practices.EnterpriseLibrary.Logging verwendet. Beim Aufruf der Seite sollen 3 Einträge mit den Typen Error, Warning und Information angelegt werden.

 

Deployment

Für das Deployment der SharePoint Solution müssen in das Package folgende Assemblies eingebunden werden, die dann ins GAC (Global Assembly Cache) installiert werden.

Microsoft.Practices.EnterpriseLibrary.Logging.dll
Microsoft.Practices.EnterpriseLibrary.Common.dll
Microsoft.Practices.ServiceLocation.dll
Microsoft.Practices.Unity.dll
Microsoft.Practices.Unity.Interception.dll

 

Nachdem die Entwicklung abgeschlossen ist und alle erforderlichen Assemblies eingebunden wurden kann die Solution deployed werden.

 

 

Testing


Nach Aufruf der Seite http://localhost/_layouts/SharePointEntLibLogging/LoggingTest.aspx

wurden wie erwartet 3 Einträge in der Ereignisanzeige mit dem Inhalt Test erstellt.

 

 

 

Tags: ,

Inkonsistente Datenspeicherung mit TransactionScope verhindern

23.10.2011 | 18:34

Wer kennt das nicht, beim Speichern von abhängigen Daten in eine Datenbank passiert plötzlich ein Fehler. Das Resultat, ein Teil der Daten wurde gespeichert, der Rest konnte aufgrund des Fehlers nicht gespeichert werden. Um solche inkonsistente Daten zu vermeiden, kann man die Klasse TransactionScope aus dem Namespace System.Transactions verwenden. Alle Operationen werden erst in die Datenbank gespeichert, wenn keine Fehler innerhalb der TransactionScope passiert sind.

Ich habe ein Beispiel Szenario erstellt, bei dem ein Task (Aufgabe) mit zugehörigen Worker (Arbeitern) gespeichert werden soll.

Auf Datenbankebene gibt es die Tabelle Task und Worker.

 

Die zugehörigen Datenobjekte sehen folgendermaßen aus:
 

  


Das Beispiel Projekt hat folgenden Aufbau:

 
In der Program.cs wird ein Task-Objekt und zwei zugehörige Worker-Objekte erstellt:

 

 

Dieser Task wird anschließend an den TaskService übergeben...

 

Innerhalb der Save Funktion wird ein TransactionScope erstellt und die Daten werden nacheinander an die Klasse Database zum Speichern übergeben.

 

 

Die Daten werden erst gespeichert, wenn alle Operationen ohne Fehler durchgelaufen sind. Wenn ein Fehler beim Speichern eines Worker passiert, kommt es nicht zum Aufruf von transactionScope.Complete() und der Task wird somit nicht gespeichert. Würde der TransactionScope fehlen, dann wäre nur der Task ohne die zugehörigen Worker gespeichert.

 

Zum Test setze ich eine Exception nach dem SaveTask Aufruf ein, um einen Fehler zu simulieren...

 

 

Das interessante ist nun, ob in der Tabelle Task ein Datensatz gespeichert wurde...

 

...wie erwartet wurde kein Datensatz gespeichert.

 

Nach entfernen der Exception, werden die Daten ohne Probleme gespeichert...

Task

Work

 

Beim Speichern in die Datenbank wurde zum einen das klassische ADO.NET SqlCommand Objekt verwendet, das direkt gegen die Tabellen speichert. Ein weiterer Test war das Aufrufen von StoredProcedures, die das Speichern ermöglichen. Beides lief problemlos bei einem manuell erstellten Fehler mit der TransactionScope.

Tags:

PDF Generierung mit dem ReportViewer

06.08.2011 | 17:55

Möchte man schnell ein PDF Layout mit Platzhaltern für eigene Parametern erstellen, so kann der ReportViewer hier Abhilfe schaffen. Mithilfe des Designers für Report Dateien lassen sich schnell eigene Layouts anlegen.

Im folgenden Beispiel wird eine ASP.NET Seite verwendet, die zwei Eingabeparameter in ein Report Layout an bestimmte Platzhalter setzt und anschließend eine PDF Datei zum Download generiert. Zusätzlich wird noch die Kopf- und Fußzeile verwendet, um eigene Bilder bzw. die Seitenanzahl anzuzeigen.

 

Nun zum Projekt, die Solution hat folgenden Aufbau..

Die CustomReport.rdlc ist eine Report Datei, die das Aussehen definiert, welches im Designer angepasst werden kann, wie im folgenden Beispiel zu sehen ist.

 

 

Es wurden links im Report Data Fenster unter Parameters eigene Parameter definiert, die später auf das Formular platziert werden sollen. Hierzu kann man per Drag&Drop einfach die erstellten Parameter an eine gewünschte Position platzieren. Per Rechtsklick auf das Formular lassen sich weitere Elemente hinzufügen, wie z.B. Tabellen, Matrizen, Listen oder Charts.

 

Die ASPX Seite hat nur zwei TextBox Controls für die Eingabe der Parameter...

 

Im Click EventHandler des Buttons wird folgender Code ausgeführt, der die Parameter setzt und dem Reportviewer übergibt.

 

protected void GenerateClicked(object sender, EventArgs e)
{
    ReportViewer1.LocalReport.ReportPath = HttpContext.Current.Server.MapPath("~/App_Data/Reports/CustomReport.rdlc");
    ReportViewer1.LocalReport.EnableExternalImages = true;

    //Parameter mit Werten setzen.
    ReportParameter firstName = new ReportParameter("Firstname", tbFirstname.Text);
    ReportParameter lastName = new ReportParameter("Lastname", tbLastname.Text);
    ReportParameter createdDate = new ReportParameter("CreatedDate", DateTime.Now.ToString());

    //Parameter zum Report hinzufügen
    ReportViewer1.LocalReport.SetParameters(firstName);
    ReportViewer1.LocalReport.SetParameters(lastName);
    ReportViewer1.LocalReport.SetParameters(createdDate);


    Byte[] results = ReportViewer1.LocalReport.Render("PDF");

    Response.ContentType = "Application/pdf";
    Response.AddHeader("content-disposition", "attachment; filename=pdf01.pdf");
    Response.OutputStream.Write(results, 0, results.Length);

    Response.End();
}

 

Anschließend wird die PDF Datei erstellt und zum Download angeboten.

 

 

 

Um die ReportViewer Funktionalität nutzen zu können, muss folgende Referenz hinzugefügt werden: Microsoft.ReportViewer.WebForms (Web)

 

Viel Spaß beim Testen Smile

 

Download: ReportViewer2PdfSample.zip (19,21 kb) [Downloads: 294]

Tags: ,

Windows Phone Konsole aktivieren

28.05.2011 | 13:47

Im Windows Phone Emulator lassen sich keine Systemanwendungen debuggen, aber es lassen sich die Ereignisse des Emulators über einen Konsolenfenster ausgeben.
Um das Konsolenfenster zu aktivieren muss folgendes gemacht werden:

 

1) Registry öffnen (regedit)

2) Zum folgenden Key navigieren

x86 Systeme:    

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\XDE

oder

x64 Systeme:

  • HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\XDE

3) Erstelle ein neuen DWORD-Wert mit dem Namen EnableConsole und dem Wert 0x00000001 (1)


Wenn der Emulator gestartet wird, werden alle Systemereignisse in dem Konsolenfenster angezeigt.

 

Tags:

Update: AutoCompleteSearch mit direkter Umleitung...

11.04.2011 | 23:23

Es ist soweit, mit der BlogEngine Extension AutoCompleteSearch kann durch die Selektion eines Suchergebnisses, direkt auf die Beitragsseite umgeleitet werden. Ihr könnt es gleich hier bei mir testen Smile

Auf das Feature wurde ich durch Dennis Alexander Petrasch aufmerksam, welcher gleich eine Lösung vorgeschlagen hat. In der vorgeschlagenen Lösung muss die Post.cs aus der BlogEngine.Core.dll angepasst werden, was bei einem späteren Update problematisch sein kann, da diese wieder angepasst werden muss. Aus diesem Grund habe ich versucht eine andere Lösung zu finden, die "weniger" Anpassungen erfordert. 

 

Vorhandene AutoCompleteSearch Extension aktualisieren

 

1) In der AutoCompleteSearch.ascx Datei muss das AutoCompleteExtender  Control durch das clientseitige Event OnClientItemSelected erweitert werden:

 <ajaxtoolkit:AutoCompleteExtender  ...
...
OnClientItemSelected
="ProcessSelectedPost">


2) Die neue ProcessSelectedPost JavaScript Funktion kommt auch in die AutoCompleteSearch.ascx oberhalb des <div id="searchbox"> Elements

<script language="javascript" type="text/javascript">
 
    function ProcessSelectedPost(source, eventArgs) {
             
            var value = eventArgs.get_value();
            value = value.replace('"''').replace('"''');         
 
            location.href = value;       
        }
 
</script>

 

3) Als letztes muss der WebService angepasst werden. Hierfür muss die DataWebService.asmx geöffnet werden.

Es kommen folgende using Statements hinzu:

using System.Web.Script.Serialization;
using AjaxControlToolkit;


Die komplette GetFoundData Funktion kann durch die folgende ersetzt werden:

 

private static List<string> GetFoundData(IEnumerable<string> titles, string prefixText)
    {
        List<string> items = new List<string>();
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        
        foreach(string title in titles)
        {
            if (title.ToLower().Contains(prefixText.ToLower()))
            {
                string url = Post.Posts.Where(x => x.Title.ToLower() == title.ToLower())
                                 .Select(x => x.AbsoluteLink.AbsolutePath).Single();
                    
                items.Add(AutoCompleteExtender.CreateAutoCompleteItem
                              (title, serializer.Serialize(url)));
            }
        }

        return items;
    }


Das wären alle Anpassungen, um das neue Feature auf eurem Blog zu nutzen.

 

Was hat sich grundlegendes geändert?

Beim WebService werden die gefilterten Posts mit der jeweiligen URL als KeyValue Paar an das AutoCompleteExtender Control übergeben. Auf der Client Seite wird durch das Auslösen des OnClientItemSelected Events die ProcessSelectedPost Funktion aufgerufen. Diese erhält über die eventArgs den Key(Text) und Value(Url) übergeben, welcher dann auf die jeweilige Seite weiterleitet.

 

Für alle neuen Nutzer wurde die Installation der Extension auf der folgenden Seite aktualisiert und veröffentlicht.

AutoCompleteSearch für BlogEngine

Tags: