Auf der Suche nach einer guten Lösung um E-Mails via Template versenden zu können habe ich heute ein interessantes Open-Source Projekt gefunden. Town Crier ist eine smarte Lösung, um nicht selber ständig so etwas per "string.replace" machen zu müssen - bzw. sich selber mit dem Gedanken auseinander setzen zu müssen eine Template-Engine in .NET zu entwicklen. Den .NET Source-Code für dieses Projekt kann hier im GitHub-Repository runterladen! Entwickelt wurde die Engine in C# und steht unte der "Lesser GNU Public Licence". Eine kurze Einführung findet man hier.
Bei einem Ur-Alt Portal (DotNetNuke 3.2.2) das noch hobbymäßig betreut habe, steht nun der Wechsel zu einer anderen Plattform an. Da der Benutzer aber kein neues Passwort bekommen sollten, müssen die existierenden Passwörter aus DNN exportiert werden. Die Passwörter wurden über das ASP.NET Membership Model verwaltet und die Passwörter sind nicht als Klartext sondern verschlüsselt in der Datenbank vorhanden. Ein simpler Export der Daten nutzt also an dieser Stelle nichts. Daher habe ich mich heute Abend hingesetzt und eine Quick and Dirty-Lösung entickelt, die es erlaubt einen Webservice aufzurufen, der dann wiederum eine CSV-Datei auf dem Server erstellt. Warum dann einen Webservice? Nun, zunächst hatte ich mir das etwas anderes gedacht - bin dann aber aus lauter Faulheit dazu übergegangen die Daten direkt lokal zu speichen. Von Quellcode her nicht wirklich optimal und wohl alles andere als CCD-konform .. aber es funktionierte für meinen einmaligen Zweck. Sollte das noch öferts anstehen, muss man über eine allgemeingültigere Lösung nachdenken und auch die Export-Funktion anpassen. Obwohl der Code nicht gerade ne Refernz ist, möchte ich diesen veröffentlichen und vielleicht hilft es ja dem einen odere anderen ebefalls die Passwörter seiner DotNetNuke User zu entschlüsseln. An alle Kritiker des Datenschutzes: Ja das habe ich auch anbemängelt, allerdings wollte das mein Gegenüber so habe. Bitteschön UserWebService.zip (7,65 KB)
Im Breadcrumb Skinobject von DotNetNuke wird per Default immer der Seitenname angezeigt. Es kann aber durchaus Fälle geben, bei denen es sinnvoll ist nicht den Seitennamen sondern den Seitentitel anzeigen zu lassen. Der Seitennamen ist die Bezeichnung im Menü und der Seitentitel ist der Browsertitel. Wenn man nun anstelle vom Seitenamen den Seitentitel nutzen möchte, dann kann man dieses per Konfiguration der Komponente ganz einfach erreichen. Hier gibt es die Eigenschaft "UseTitle" und wenn diese mit dem Wert "true" belegt wird, beeinflusst das die Darstellung. Hier als Beispiel: <dnn:BREADCRUMB runat="server" id="dnnBREADCRUMB"
CssClass="Breadcrumb" RootLevel="0"
Separator=" > " UseTitle="True" />
Das Socialmedia Publisher Projekt wurde in der zwischenzeit um eine Anbindung an einen URL Shorter Dienst erweitert. Damit man für die unterschiedlichen Socialmedia Plattformen (Twitter, Facebook, etc.) möglichst flexible bleibt, wurde bei der Implementierung das auch in DotNetNuke sehr oft verwendete Provider Pattern verwendet. Der Vorteil dabei ist, dass erst zur Ausführungszeit entschieden wird, welche konkrete Implementierung verwendet wird. Somit ist es also möglich für Facebook z.B. TinyURL zu verwenden und bei Twitter bit.ly. Die dafür benötigte abstracte Klasse sieht so aus: public abstract class URLShorterProvider
{
#region [ Shared/Static Methods ]
private static URLShorterProvider _urlShorterProvider = null;
public static URLShorterProvider Instance(string typeName)
{
URLShorterProvider urlShorterProvider = null;
CacheManager uscProviderCache = null;
try
{
uscProviderCache = CacheFactory.GetCacheManager ("URLShorterProviderCache");
}
catch
{ }
if (uscProviderCache != null)
urlShorterProvider = (URLShorterProvider)uscProviderCache .GetData ("USC" + typeName);
if (urlShorterProvider == null)
{
urlShorterProvider = (URLShorterProvider)TC.Framework. ProviderPattern.ProviderBase.InitInstance(typeName);
if (uscProviderCache != null)
uscProviderCache.Add("USC" + typeName, urlShorterProvider, CacheItemPriority.High, null, new NeverExpired());
}
return urlShorterProvider;
}
#endregion
#region [ abstract methods ]
public abstract string ShortUrl(string url);
#endregion }
Genutzt wird hier das singelton Pattern in Kombination mit einem Caching. Die eigentliche Implementierung für TinyURL ist sehr einfach gehalten und sieht wie folgt aus: public class TinyURL : URLShorterProvider
{
///Die maximale Länge der URL, bevor diese gekürtzt wird.
private const int MAX_URL_LENGTH = 26;
public override string ShortUrl(string url)
{
try
{
if (url.Length < MAX_URL_LENGTH)
return url;
return new System.Net.WebClient().DownloadString ("http://tinyurl.com/api-create.php?url=" + System.Web.HttpUtility.UrlEncode(url));
}
catch(Exception exc)
{
Diagnostics.ExceptionHelper.HandleException(exc);
return "";
}
}
}Mit dieser Methode kann man nun sehr einfach und ohne großen Aufwand neue URLShoter-Dienste anbinden und per Konfiguration diese Dienste dann zuordnen.
Das bisher in der DotNetNuke Professional verfügbare RibbonBar Control Panel - eine Alternative zu dem normalen ControlPanel - steht jetzt auch für die Community Version zur Verfügung. Im Vergleich zu dem normalen Control Panel, hat der Bearbeiter hier deutlich mehr Möglichkeiten die wichtigen Parameter direkt zu beinflussen. Das RibbonBar Control Panel ist aufgeteilt in für Tabs / Bereiche: - Common Tasks
- Current Page
- Admin
- Host
Der Bereich Commen Tasks ist relativ identisch zu den bisher eingesetzten Control Panel. Zumindest auf den ersten Blick. Hier sind aber auch einige wirklich sinnvolle Erneuerungen aufgenommen. Bei der Neuanlage einer Seite kann man jetzt hier direkt die Informationen Name, Position in der Sitemap, Template, etc. definieren. Das kopieren von bereits existierenden Modulen von anderen Seiten wurde angepasst und kann man nicht nur eine Referenz von einem Modul nutzen, sondern auch ein komplett neues Modul mit den identischen Inhalten und Einstellungen erzeugen - also ein wirklicher 1:1 Kopiervorgang von einem bestehenden Modul. Der Bereich "Current Page" ist neu und bietet die Möglichkeit wichtige Parameter wie Name, Position in der Sitemap oder das vererben von Rechten direkt durchzuführen. Die beiden Bereiche Admin und Host zeigen die Punkte aus dem Administrationmenü an. Das finde ich ganz praktisch, das es immer wieder mal Unterseiten gibt, die über kein Hauptmenü verfügen und somit war man nie in der Lage direkt in einen Bereich von Admin oder Host zu gelangen.
Bei Anwendern die mit einer aktuellen Version vom Firefox 3.6 DotNetNuke administrieren möchten, haben ein Problem an das Kontext-Menü eines Modul zu kommen, da dieses einfach nicht sichtbar ist bzw. nicht angezeigt wird. Um dieses Problem zu beheben muss man in der JavaScript-Datei vom Solpartmenu eine Zeile verändern und dort den z-Index erhöhen. Die entsprechende JavaScriptdatei für das Menü befindet sich vom DotNetNuke-Root aus im Verzeichnis "/controls/SolpartMenu/spmenu.js". In der Zeile 948 befindet sich ein Eintrag: eMenu.style.zIndex = 1 Die Wert von 1 einfach erhöhren z.B. 10000 und anschliesend wird das Kontext-Menü von den DotNetNuke Modulen auch wieder im Firefox angezeigt.
In einem vorherigen Blogpost habe ich über meine Pläne eines Social Networks Publishing-Dienst berichtet. Mittlerweile haben diese Pläne bereits ganz konkrete Formen angemonnen. Eine Herausforderung an dem ganzen Dienst war es, die Aufbereitung der Nachrichten für die einzelnen Dienste wie Twitter, Facebook, etc. Jedes Netzwerk hat andere Möglichkeiten und ich wollte nicht das mögliche Beschränkung" eines einzelnen Social Network alle weiteren in Ihren Möglichkeiten beschränken. Damit man möglichst den vollen Umfang einer Plattform nutzen kann ist es also erforderlich, die jeweiligen Parameter konfigurierbar zu gestalten. Der Ablauf ist nun wie folgt: Es gibt eine zentrale Schnittstelle die z.B. eine Nachricht in der gesamten Länge aufnimmt. Bei der Übergabe wird gleichzeitig definiert für welche Social Plattformen die Nachricht bestimmt ist. Nun wird für jede Plattform die entsprechenden Einstellungen / Konfigurationen geladen, um anschließend die Nachricht für jede Plattform individuell aufzubereiten. Die "fertige" Nachricht wird in einer Datenbank gespeichert und zur Veröffentlichung frei gegeben. Das bedeutet natürlich das die eingehende Nachricht für jede anzusprechende Plattform einen eigenen Eintrag bekommt. Diese Redundanz ermöglicht es eine individuelle und optimierte Nachricht zur Verfügung zu stellen. Nebenbei läßt sich darüber auch eine zeitgesteuertes Veröffentlichung je Plattform realisieren. Die Anbindung eines URL-Shorter für die Links wird der nächste Schritte bei der Implementierung.
Vor ein paar Jahren habe ich mal eine Klasse entwickelt, die es erlaubt mit ASP.NET ein HTML-Formular abzusenden, ohne dieses wirklich auf der ASPX oder ASCX Seite im HTML Quellcode stehe zu haben. So etwas ist z.B. sehr nützlich, wenn man externe Schnittstellen mit Daten beliefern möchte. Die Basics dazu können in meinem ersten Artikel Posting Form Data with c# nachgelesen werden. Im Zuge der Entwicklung meines Social Networks Publishing-Dienst, kam ich heute aber an die Grenze der Klasse, da ich eine Schnittstelle nicht über das HTTP-Verb POST sondern GET ansprechen muss. Zunächst sah dieses recht einfach aus, da man bei der .NET Klasse HttpWebRequest das Verb über die Property METHOD definieren kann. Allerdings bekam ich beim Versenden des Formulars - oder viel mehr beim Aufruf der URL immer eine Fehlermeldung: "Inhaltsteil mit diesem Verbtyp kann nicht gesendet werden." Nach genauer Betrachtung was passiert war mir klar, dass es nicht direkt der Aufruf der URL ist, der diesen Fehler verursacht sondern viel mehr die Tatsache das die Klasse ja versucht einen Stream öffnet um die POST-Daten damit zu übermitteln. Bei der Methode GET ist dieses aber nicht notwendig und somit wird die Verarbeitung mit der Fehlermeldung abgebrochen. Damit die Methode "Send" der Klasse nun sowohl POST als auch GET verarbeiten kann, habe ich den Code wie folgt verändert. public string Send(string content2Post)
{
string sPostData = "" ;
//Zusammensetzen der Daten für die Übermittlung
if (string.IsNullOrEmpty(content2Post))
sPostData = GetContentToPost();
else
sPostData = content2Post;
Uri sUri = null;
HttpWebRequest request = null;
if (this.Method == "POST")
{
sUri = new Uri(this.Url) ;
request = (HttpWebRequest)WebRequest.Create(sUri);
request.Method = Method; // "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = sPostData.Length;
Stream writeStream = request.GetRequestStream();
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] bytes = encoding.GetBytes(sPostData);
writeStream.Write(bytes, 0, bytes.Length);
writeStream.Close();
}
else
{
sUri = new Uri(string.Concat(this.Url, "?", sPostData)) ;
request = (HttpWebRequest)WebRequest.Create(sUri);
request.Method = Method;
request.ContentType = "text/plain";
request.ContentLength = 0;
}
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
//Überprüft den HTTP-Statuscode
if (response.StatusCode != HttpStatusCode.OK)
return "N,-1, HTTPStatuscode:" +response.StatusCode.ToString() ;
Stream responseStream = response.GetResponseStream();
StreamReader readStream = new StreamReader (responseStream, Encoding.UTF8);
return readStream.ReadToEnd();
}
Nur wenn die Methode POST gewählt wurde, wird ein Stream genutzt um die zu übermittelnden Daten dort unterzubringen.
Das iPhone und auch der iPod-Touch findet immer mehr anklang und die Anzahl der Nutzer wird wohl in den nächsten Monaten und Jahren mehr zu- als abnehmen. Grund genug sich mit dem Thema zu beschäftigen. Für Menschen im Microsoft .NET Umfeld gibt es jetzt ein eBook "Building iPhone and iPod touch Applications for the .NET/C# Developer with MonoTouch" das erklärt wie man mit Hilfe von C#, MonoTouch und MonoDevelop eine iPhone App entwickeln kann. Das ist doch mal cool. Hier der Link zum eBook
Die Bedeutung Social Networks / Social Media (bzw. Soziale Netwerke) wächst im Augenblick fast täglich. Twitter, Facebook, StudiVZ als Netzwerke aber auch die Social Bookmark Dienste von Google, Microsoft Live, etc. werden deutlich mehr genutzt. Diese Netzwerke werden nicht nur von Kindern und Computergeeks genutzt sondern auch von vielen Firmen, um darüber den Geschäftserfolg zu steigern. Wer nicht in den meisten Netzwerken vertreten ist, vergibt sich unter Umständen jede Menge Chancen. Jetzt kann es aber sehr Aufwendig sein, alle Netzwerke immer mit den Inhalten zu füllen – dabei lässt sich das wirklich gut automatisieren, da viele von den Social Networks (z.B. Twitter) eine API anbieten um Inhalte von externen Tools zu publizieren. Mittlerweile gibt es bereits einige Dienste im Internet, die in der Lage sind verschiedene Netzwerke mit einem Tool zu bedienen. Für meinen Teil habe ich mich entschieden eine eigene Anwendung zu schreiben – nein, nicht aus wirtschaftlichen Gründen sonder einfach weil ich Spaß daran habe – also keine Diskussionen bitte warum ich das Rad noch mal erfinden .. ich hab gerade Spaß dran  Derzeit plane ich ein Publishing-Dienst mit der WCF (Microsoft Windows Communication Foundation) zu erstellen, der über eine universelle Schnittstelle gefüttert werden kann, um dann schließend die Nachrichten in den angegebenen Netzwerken zeitgesteuert zu veröffentlichen. Zur Entkopplung zwischen der universellen Schnittstelle und dem eigentlichen Dienst kommt nach Planung eine Message Queue (MsMq) zum Einsatz, damit die Schnittstelle unabhängig von Dienst zur Verfügung steht um Nachrichten im Empfang zu nehmen. Der eigentliche SocialMedia-Publishing-Dienst soll sich dann darum kümmern das die Nachrichten entsprechend es gewählten Netzwerks aufbereitet werden – z.B. die Länge der Nachricht, Verwendung von URLShorter-Diensten (TinyUrl), usw. Die benötigten Informationen bzw. Konfigurationen werden in einer Datenbank gespeichert, wo auch die einzelnen aufbereiteten Nachricht abgelegt werden. Ein Veröffentlichungsprotokoll rundet dann die Anwendung ab, damit man verfolgen kann, wann welche Nachricht veröffentlicht wurde oder eben warum nicht. Zur Verwaltung des Publishing-Dienst stelle ich mir aktuelle eine kleine ASP.NET MVC Anwendung vor… Wenn jemand noch gute Ideen hat, dann immer her damit :)
In dem Text/HTML Modul vom DotNetNuke Core-Team kann man ja bereits seit einiger Zeit ein paar Token wie z.B. Benutzername, EMail, Portal-Informationen, etc. nutzen. Dafür muss man in den Einstellungen vom Modul die Replacement-Funktionalität aktivieren. Bisher konnte man die Tokens zwar nutzen, musste die Liste der verfügbaren Tokens im Kopf halten. Jetzt gibt es endlich ein Plugin für den FCK-Editor, um eine einfache Auswahl und Nutzung der Tokens zu ermöglichen. Dieses Plugin gibt es hier auf CodeplexEcht sinnvoll und nützlich im Alltag!
Microsoft .NET auf dem iPhone? Das geht? Ja! Das Projekt MonoTouch liefert eine Runetime für das iPhone um dort Anwendungen mit .NET zu entwickeln oder viel mehr um unter in .NET entwickelten Anwendungen auf dem iPhone laufen zu lassen.
Anders als bisherige .NET Anwendungen wird hier aber kein MSIL Code erzeugt, sondern direkt ausführbarer Maschienencode - es gibt also keinen JIT-Compiler auf dem iPhone und ausgeliefert wird nativer Code. Derzeit gibt es MonoTouch nur einem eingeschränkten Betatester-Kreis, das erste offizielle Release ist aber bereits für September 2009 angekündigt. Lassen wir uns überraschen :)
Weiter Infos gibt es hier:
http://www.mono-project.com/MonoTouch
Wie ich soeben in einem Blogbeitrag von Oliver S. gelesen habe ist das neues Silverlight Release 3 offiziell verfügbar. Neben vielen Erweiterungen im Multimediabereich (Live- und On-Demand True HD Smooth Streaming,Echte HD-Widergabe,Einzigartige Formatvielfalt) finde ich besonders interessante das es nun endliche eine Toolbox mit über 60 Controls (inkl. SourceCode) vorhanden ist. Das sollte die Entwicklung deutlich vereinfachen da Datagrid, Treeview, etc. "einfach" vorhanden sind. Ziemlich cool finde ich auch, dass Silverlight jetzt nicht nur im Browser sondern auch direkt als Desktopanwendung ausgeführt werden kann (okay, das musste wohl in Hinblick auf Flash auch integriert werden  ) Wer eine ausführliche Liste an Features haben möchte .. dem empfehle ich den kompletten Blog-Beitrag hier
Derzeit steht die letzte (für uns) Migration eines DotNuke-Portals von der Version 3.2.2 auf die aktuellste Version an. Da es sich hierbei um ein recht großes Portal handelt, bei dem der Communityaspekt im Vordergrund steht, wurden die Benutzerprofile hier sehr stark genutzt und erweitert. Dieses wurde in der Version 3.2.2 durch Veränderungen der web.config erreicht. Bei dem Testlauf einer Migration ist mir nun aufgefallen, dass die zusätzlich definierten benutzerdefinierten User-Propeties nicht mit in das neue Konzept übertragen werden. Um das zu erreichen, muss man das SQL-Upgradescript anpassen und die zu migrierenden Properties dort mit einfügen. Dafür muss man in das SQL-Script mit der Version 03.02.03 einige Änderungen machen: Die StoredProcedure AddDefaultPropertyDefinitions muss um die zusätzlichen Eigenschaften ergänzt werden - dabei wird der Datentyp definiert, die Gruppe, die Bezeichnung, Länge, etc. definiert. Später können diese Eigenschaften auch über die bekannte Benutzerprofilverwaltung angepasst werden. EXECUTE @RC = {databaseOwner}[{objectQualifier}AddPropertyDefinition] @PortalId, -1, @TextDataType, '', 'LowFett','Size' ,0, '', 21, 1, 250
EXECUTE @RC = {databaseOwner}[{objectQualifier}AddPropertyDefinition] @PortalId, -1, @TextDataType, '', 'LowFett','Weight' ,0, '', 21, 1, 250
EXECUTE @RC = {databaseOwner}[{objectQualifier}AddPropertyDefinition] @PortalId, -1, @TextDataType, '', 'LowFett','Eyecolor' ,0, '', 21, 1, 300
EXECUTE @RC = {databaseOwner}[{objectQualifier}AddPropertyDefinition] @PortalId, -1, @TextDataType, '', 'LowFett','Haircolor' ,0, '', 21, 1, 300Die Tabelle FlatProfile wird temp. angelegt um die Daten vom ASP-Membership zwischenzulagern. Auch hier müssen ein paar manuelle Änderungen vorgenommen werden, damit diese Tabelle für die zu migrierenden Daten auch jeweils eine Spalte bekommt - der SQL-Syntax der "normale" für den den SQL-Server - hier zwei Beispiele: [Eyecolor] [nvarchar] (300) NULL ,
[Haircolor] [nvarchar] (300) NULL ,
Dann muss die Ausführug von "INSERT INTO {objectQualifier}FlatProfile" um die entsprechenden Eigenschaften ergänzt werden: {databaseOwner}{objectQualifier}GetProfileElement('Weight',PropertyNames, PropertyValuesString) Weight,
{databaseOwner}{objectQualifier}GetProfileElement('Eyecolor',PropertyNames, PropertyValuesString) Eyecolor,
{databaseOwner}{objectQualifier}GetProfileElement('Haircolor',PropertyNames, PropertyValuesString) Haircolor,
Als letzer Schritt müssen dann noch ein paar zusätzliche SQL-Befehle eingefügt werden, damit die Daten aus der FLAT-Tabelle in die eigentlichen UserProfile-Tabelle geschrieben werden. EXECUTE {objectQualifier}TransferUsersFromFlatProfile N'Eyecolor'
EXECUTE {objectQualifier}TransferUsersFromFlatProfile N'Haircolor'
Wenn diese Schritte für jede zu migrieden benutzerdefinierte Property durchgeführt wurde, dann steht der Migration nichts mehr im Weg.
Bei der Entwicklung von DotNetNuke-Modulen (bzw. auch bei "normalen" ASP.NET Anwendungen) verwende ich recht häufig die Möglichkeit, Usercontrols (ascx) dynmaisch zur Laufzeit anzuzeigen / nachzu laden. Der entsprechende Quellcode dafür ist nicht wirklich neu und sieht so aus: PortalModuleBase objToLoad = this.LoadControl(_ControlToLoad) as PortalModuleBase;
objToLoad.ID = System.IO.Path.GetFileName(_ControlToLoad);
objToLoad.ModuleConfiguration = this.ModuleConfiguration;
this.Controls.Add(objOrderCtrl);
Wichtig dabei ist die Zeile, wo die ID des Controls gesetzt wird, damit die Resourcendateien durch DotNetNuke (durch die Property LocalResourceFile) angesprochen werden können. Bei der Verwendung einer Templateengine für ein Modul und der gleichzeitigen Verwendung von Standard ASP.NET 2.0 Validatoren, bekam ich im Browser immer die Javascript-Fehlermeldung "missing ; before statement". Nach kurzer Recherche habe ich die Ursache gefunden: In den ID's von den Controls wurde ein Punkt verwendet und damit kommt JavaScript bzw. der JavaScript-Code der ASP.NET Validatoren nicht zurecht. Nach Abänderung der ID Zuweisung auf folgende Zeile: objToLoad.ID = System.IO.Path.GetFileNameWithoutExtensi(_ControlToLoad);
funktionieren sowohl die Resourcendateien als auch die Validatoren wieder ohne Probleme.
Heute habe ich mich ein wenig mit dem Thema PCI Compliance beschäftigt, da wir mit unserem DotNetNuke Shop einen Kunden an Worldpay angebunden haben. Mittlerweile ist es aber so, dass neben einem SSL Zertifikat auch ein PCI Compliance Scan vorgenommen werden muss.
Im Internet habe ich dafür auch einen ganz guten Dienst gefunden, der das online durchführt. Derzeit bin ich in der Testphase dieser Software - sieht im Augenblick aber sehr brauchbar aus. Besonders, da hier nciht nur ein Bereicht abgeliefert wird, sondern auch direkt Hilfstellung angeboten wird, wie man das Problem beheben kann. Jeder der ebenfalls eine Software für einen PCI Compliance Scan sucht - findet diese unter http://www.qualys.com.
Sollte jemand noch eine Alternative kenne, würde ich mich über eine kurze Nachricht oder einen Kommentar freuen 
Eine Meldung bei dem eigenen Kundenserver war "SSL Insecure Protocol Negotiation Weakness", das ein Problem bzw. ein erhöhtes Risiko mit SSL v2 darstellt. Dieses sollte / muss im Internet Information Server (IIS) deaktivert werden. In der Managementkonsole vom IIS gibt es dafür aber leider keinen Schalter und die Deaktivierung erfolgt manuell über die Registry. Wie man SSL v2 bei einem Windows Serverr mit IIS deaktivieren kann ist in der Knowledge Base von Microsoft nachzulesen: http://support.microsoft.com/kb/187498
Nach einem Reboot vom Server wird auch dieser Punkt vom PCI Scanner als "erledigt" dargestellt.
Seit einiger Zeit arbeite wir sehr zufrieden mit Subversion, lediglich die bisher nicht bekannte fehlende Unterstützung von Visual Studio 2005 / 2008 war ein "Dorn im Auge". Jedoch gibt es auch dafür eine Lösung und die nennt sich AnkhSVN.
Dabei handelt es sich um eine AddOn für Visual Studio, dass die benötigte Funktionalität für die tägliche Arbeite direkt im Visual Studio zur Verfügung stellt. Per Kontextmenü kann man nun Projekte in Subversion übertragen oder ähnliches.
Das AddOn Clienttool "AnkSVN" für Visual Studio gibt es hier.
Habe heute das Servicepack 1 für das Visual Studio 2008 und .NET 3.5 installiert. Nach der Installation konnte ich unter Visual Studio 2005 keine ASP.NET Anwendungen mehr debuggen. Als Fehlermeldung kam immer diese Meldung:
"Das Debuggen kann auf dem Webserver nicht gestartet werden. Authentifizierungsfehler bei der Kommunikation mit dem Webserver."
Das Durchsuchen der Supportdatenbank von Micrsoft hat mich dann auf folgenden Artikel "Fehler 401.1 beim Aufrufen einer Website, die integrierte Authentifizierung verwendet und mit IIS 5.1 oder IIS 6 gehostet wird" aufmerksam gemacht http://support.microsoft.com/kb/896861.
Bei mir hat diese beschrieben Methode zum Erfolg geführt:
- Klicken Sie auf Start und auf Ausführen, geben Sie regedit ein, und klicken Sie auf OK.
- Suchen Sie im Registrierungseditor den folgenden Schlüssel, und klicken Sie auf ihn:
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
- Klicken Sie mit der rechten Maustaste auf MSV1_0, zeigen Sie auf Neu, und klicken Sie anschließend auf Wert der mehrteiligen Zeichenfolge.
- Geben Sie BackConnectionHostNames ein, und drücken Sie anschließend die [EINGABETASTE].
- Klicken Sie mit der rechten Maustaste auf BackConnectionHostNames. Klicken Sie dann auf Ändern.
- Geben Sie in das Feld Wert den Hostnamen bzw. die Hostnamen für die Sites ein, die sich auf dem lokalen Computer befinden, und klicken Sie danach auf OK.
- iisreset zum Neustarten des IIS ausführen.
Gerade beschäftige ich mich ein wenig mit dem Thema Caching und dabei kommt man ja irgendwie an Memcached nicht vorbei. Wollte memcached dabei als Service in Vista laufen lassen, doch beim Aufruf in der Commandozeile
c:\memcached\memcached.exe -d install
kommt ständig die Fehlermeldung:
"failed to install service or service already installed"
relativ schnell habe ich herausgefunden das es an den unzureichenden Rechten meines Benutzeraccounts unter Vista liegt. Damit es funktioniert muss man die Console als Administrator ausführen.
Dafür gibt es einen Shortcut: Wenn man bei der Ausführung der Anwendung Ctrl+Shift+Enter drückt, kann man sich den Weg über das Kontextmenü sparen.
Bei einem Server fand ich im Eventlog ständig folgenden Eintrag:
Ereigniscode: 3005 Ereignismeldung: Es ist eine unbehandelte Ausnahme aufgetreten. Ereigniszeit: 02.10.2008 01:22:41 Ereigniszeit (UTC): 02.10.2008 12:22:41 Ereignis-ID: cfc0fb0037c3473d9a93aed3556026c4 Ereignissequenz: 1658 Vorkommen: xx Ereignisdetailcode: 0 Anwendungsinformationen: Anwendungsdomäne: /LM/W3SVC/1/ROOT-xxxxxxxxx Vertrauensebene: Full Virtueller Anwendungspfad: / Anwendungspfad: x:\daten\websites\xxxxxx Computername: computer Prozessinformationen: Prozess-ID: 3028 Prozessname: w3wp.exe Kontoname: IrgendeinKonto Ausnahmeinformationen: Ausnahmetyp: CryptographicException Ausnahmemeldung: Zeichenabstände sind ungültig und können nicht entfernt werden. Anforderungsinformationen: Anforderungs-URL: http://xxxxx/WebResource.axd?d=yMHoWq6OlLLBSdXLzX0Yig2&t=633563938783503750
Anforderungspfad: /WebResource.axd Benutzerhostadresse: xxx.xxx.xx.xxx Benutzer: Ist authentifiziert: False Authentifizierungstyp: Threadkontoname: IrgendeinKonto Threadinformationen: Thread-ID: 5 Threadkontoname: IrgendeinKonto Identitätswechsel für: False Stapelüberwachung: bei System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast) bei System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) bei System.Security.Cryptography.CryptoStream.FlushFinalBlock() bei System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo) bei System.Web.UI.Page.DecryptStringWithIV(String s, IVType ivType) bei System.Web.Handlers.AssemblyResourceLoader.System.Web.IHttpHandler. ProcessRequest(HttpContext context) bei System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication. IExecutionStep.Execute() bei System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) *************************
Dieses Problem (oder besser gesagt diese Fehlermeldung) wird durch einen nicht existierenden <maschineKey> in der web.config ausgelöst. Nach der Erstellung eines gültigen <machineKey> ist die Fehlermeldung verschwunden.
Für das Visual Studio 2008 gibt es ein sehr cooles und nützliches Add-in. Den SnippetDesigner der es einem erlaubt recht einfach eigene Snippet's zu erstellen und zu verwalten. Einfach durch das Context-Menü kann aus einem Codeblock ein Snippet erstellt werden.
Zu finden gibt es das OpenSource Projekt auf der Seite Codeplex.com.
Die schon lange erwartete neue Version von DotNetNuke mit dem Codenamen "Cambrian" hat einen weiteren Meilenstein erreicht. Die Version RC1 wird bei der OpenForce Europe vorgestellt und an Gruppe von Personen verteilt.
Sehr cool ist der Support von jQuery und XHTML, WCAG and ADA compliance. Benutzerrechte können jetzt nicht nur gewährt sondern auch entzogen werden, was in manchen Situationen das Leben verinfachen dürfte. Einige von den neuen Features wurden in die Version 4.9 übernommen und sind dort schon verfügbar.
Eine Übersicht der neuen Features von DotNetNuke 5.0 gibt es z.B. hier.
Wann es eine öffentliche Version gibt, ist bis jetzt aber noch nicht bekannt...
Soeben habe ich eine wirklich nützlichen Dienst / Service auf webservicex.net gefunden. Diese Plattform hatte ich schon fast vergessen und bin nun durch einen Zufall darauf aufmerksam geworden.
Dort gibt es einen Web-Service, mit dem man E-Mailadressen online validieren - also auf Gültigkeit - prüfen kann. Wirklich eine praktischer Dienst ... und man muss sich nicht selber mit der Validierung rumschlagen. Die Validierung geht natürlich über eine RegEx hinaus und überprüft beim Mailserver, ob es dort diese E-Mail wirklich gibt. Bei meine 20 Testläufen wurde mir zumindest immer ein korrektes Ergebnis zurück geliefert...
Zu erreichen unter der Adresse: http://www.webservicex.net/ValidateEmail.asmx
Das Debuggen von DotNetnuke Schedulern ist nicht so ganz einfach. Mit einem Break-Point und F5 ist es leider nicht getan an dieser Stelle, da die einzelnen Scheduler in einen separaten Thread laufen. Auch der Trink um Windows Services zu debuggen - das anhängen des Debuggers an den Prozess - funktioniert in diesem Fall einfach nicht.
Es gibt aber einen Weg, den Debugger per SourceCode-Aufruf zu starten. Das geht ganz einfach und ist mit einer Zeile erledigt:
System.Diagnostics.Debugger.Launch();
Dieser Aufruf bewirkt, dass man eine neue oder eine existierende Instanz von Visual Studio auswählen kann, um anschließend durch den Code zu steppen.
Ein paar weitere Infos gibt es bei Mircosoft-MSDN hier
Ich beschäftige mich gerade mal etwas intensiver mit dem AJAX-Framework - eigentlich ja schon ein alter Hut. Dabei habe ich ein DotNetNuke-Modul, dass zu einem ASMX-WebService Daten versendet und ein Ergebnis zurück bekommt.
namespace G.Modules.LicCalc {
[WebService(Namespace = http://tempuri.org/)] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ScriptService] public class CalculatorService : System.Web.Services.WebService {
[WebMethod()] public string HelloWorld(LicCalcInfo info) { return "Hello World" + info.LinuxLicense.ToString(); } } }
Passend dazu gibt es eine Klasse "LicCalcInfo" - die wie DotNetNuke-typische Info-Class aufgebaut ist
using System;
namespace GMS.Modules.LicCalc.Business { public class LicCalcInfo { private int _windowsLicense; private int _linuxLicense;
public int LinuxLicense { get { return _linuxLicense; } set { _linuxLicense = value; } }
public int WindowsLicense { get { return _windowsLicense; } set { _windowsLicense = value; } }
} }
Wenn ich jetzt über JavaScript versuche die Methode "HelloWorld" aufzurufen und den Parameter LicCalcInfo übergeben möchte, wird bei der Erstellung der Klasse immer eine JavaScript-Exception ausgelöst. Das JavaScript sah so aus:
function HelloWorld() {
var info = new LicCalcInfo(); info.LinuxLicense = 10; DocuSnap.Modules.LicCalc.CalculatorService.HelloWorld(info, SucceededCallback);
}
function SucceededCallback(result, eventArgs) { alert(result); }
Das ganze funktioniert aber nur, wenn die Klasse "LicCalc" direkt in der ASMX Datei definiert wurde und sich außerhalb des Namespaces befindet. Als extern definierte Klasse habe ich die Einbindung nie geschafft. Die Lösung dabei ist aber mal wieder relativ einfach: Bei der Erzeugung des Objektes in JavaScript muss das Objekt mit dem kompletten Namespace angesprochen werden.. das hat mir dann ein Blick in die automatisch gernierte JavaScript-Datei veraten. Der Aufruf zur Erzeugung muss dann so geschrieben werden:
var info = new DocuSnap.Modules.LicCalc.Business.LicCalcInfo();
Dann kann die Klasse auch in JavaScript erzeugt werden und die Verarbeitung wird erfolgreich durchgeführt.
Eigentlich habe ich ja ein paar Module (News, FAQ) für DotNetNuke gesucht - dabei bin ich dann über ein Game gestolpert, dass jeder von uns kennt und auch gerne spielt: Schiffe versenken :)
Auf der Seite http://www.donein.net/Default.aspx?tabid=58 gibt es sowohl einen Downloadlink als auch die Möglichkeit, das Spiel direkt mal zu testen!
Viel Spaß :)
Habe soeben eine ziemlich schön (zumindest auf dem ersten Blick) ASP.NET Komponente entdeckt, die einem die relativ einfach Möglichkeit bietet serverseitige Variablen an den Client Browser zu übergeben. Dafür gibt es hier eine Klasse, die einem die Verwaltungsarbeit abnimmt.
Der Weg: var CustomerName = '<%= Customer.Name %>'; ist ja nicht wirklich elegant und ich persönlich finde es immer schlechten Stil, wenn man in einer ASPX-Seite anfängt und Serverseitigen Code schreibt. [Nein, bitte keine Grundsatzdiskussion - einfach meine Meinung :)]
Viel optimaler unter ASP.NET ist doch die folgende Möglichkeit: protected void Page_Load(object sender, EventArgs e) { wwScriptVariables scriptVars = new wwScriptVariables(); // *** Add any values static or dynamic scriptVars.Add("CustomerName", Customer.Name); // *** Done}
Auf dem Client kommt das dann in folgender Form an
Automatisch werden dann die definierten Variablen an den Browser als JavaScript übermittelt und sieht so aus:
<script type="text/javascript">
//<![CDATA[ var serverVars = { "name": "Müller, Maier, Schmitu" } //]]> </script>
Ein Zugriff innerhalb von JavaScript gestaltet sich auch denkbar einfach: var name = serverVars.name;
Also ich finde diese Lösung verdammt sexy und für den täglichen Alltag auf jeden Fall zu gebrauchen!
Hm, also wenn ich die Wahl habe .. dann entscheide ich mich für Hawaii :) Wie ich gerade gehört habe ist das der Codename für .NET 4.0! Ob .NET 4.0 genau so klasse wird wie Hawaii wird sich zeigen ..
Das Framework soll voraussichtlich im Jahr 2009 erscheinen... lassen wir uns überraschen, was Microsoft da zaubert!
Folgendes habe ich gerade auf der DotNetNuke Seite gelesen und mich sehr darüber gefreut. Im wesentlichen geht es dabei um eine Neustrukturierung des Administrationkonzeptes. Zukünftig soll es möglich sein auch selber Administrationsmodule zu entwicklen und diese dann einfach in das Admin-Menü mit aufnehmen (ohne Eingriffe in die Datenbank). Ganz spannend finde ich auch, dass man die Berechtigung für die einzelnen Admin-Seiten auch endlich über die ganz normalen Seitenberechtigung steuern kann. Damit ist es dann super easy einzelnen Leuten (Gruppen) die Berechtigung für div. Adminseiten zu erteilen.
Ich bin gespannt was die Zukunft hier bringt - hört sich auf jeden Fall gut an.
Den Artikel (Blogeintrag) gibt es hier...
Auch während Weihnachten war das DNN-Core-Team wohl nicht ganz untätig und hat am 27.12.2007 den Download der DotNetNuke Version 4.8.0 frei gegeben. Es wurden viele Fehler korrigiert und neu ist der Support von DNN für den IIS (Internet-Information-Server) 7.0. Wer sich einen genauen Überblick von den Änderungen der aktuellen DNN Version machen möchte - Bitteschön, wie immer geht das im Bugtracking System support.DotNetNuke.com
Wer auf einen Blick die wichtigsten Visual Studio Shortcuts sehen möchte, dem kann ich folgendes PDF empfehlen. Diese Liste der Shortcuts ist sicherlich nicht vollständig, allerdings für die tägliche Arbeit schon holfreich. Zumindest kann so teilweise auf die Maus verzichten....
Immer wieder kommt die Situation das man im Laufe eines .NET Programmes überprüfen muss ob eine Objekt wirklich existiert oder aber ob in der Variablen der Wert NULL enthalten ist. Vielfach möchte man auch einfach für den NULL Fall einen Defaultwert setzen. Mit dem ?? Operator ist das in .NET C# sehr elegant und einfach zu realisieren.
Hier ein ganz einfaches Beispiel:
string resultmessage = param ?? "Keine Nachricht da ";
In der MSDN findet man dazu auch nähere Informationen (hier )
Hier eine Liste der wichtigsten (zumindest für mich) Escape-Sequencen:
-
\t Tab (Unicode 0x0009).
-
\r Carriage return (0x000d).
-
\n Newline (line feed) (0x000a).
-
\v Vertical tab (0x000b).
-
\a Alert (0x0007).
-
\b Backspace (0x0008).
- \0 Null (0x0000).
-
\\ Backslash (0x005c).
-
\' Single quote (0x0027).
-
\" Double quote (0x0022).
In der kommenden Version von DotNetNuke (DNN 4.6.0) ist ein sehr interessantes Feature die Möglichkeit der Implementierung von neuen Authentifizierungssystemen jenseits von DNN. Nun ist es nicht nur mehr möglich sich gegen DotNetNuke oder einer ADS (Active Directory Service) zu authentifizieren, sondern eine Anmeldung kann nun durch:
Dafür wurde ein "neues" Providermodell für die Authentifizierung implementiert. In den letzten Tagen habe ich für einen Kunden bereits einen eigenen Provider für eine Anmeldung bei der zentralen Golf-Online-Seite erstellt und erste positive Erfahrungen damit gesammelt. Dafür muss man lediglich drei UI-Komponenten entwickeln: Login, Settings and LogOff – jeweils von Basisklassen abgeleitet (AuthenticationLoginBase, AuthenticationSettingsBase and AuthenticationLogOffBase). Die Konfiguration der einzelnen verfügbaren Provider wird über die Tabelle Authentication vorgenommen. Dort wird ganz einfach ein Prefix und die drei UI-Komponenten angegeben.
Es ist auch möglich dem Benutzer die Auswahl selber zu überlassen, mit welchem Dienst er sich Authentifizieren möchte – das find ich insgesamt schon ziemlich sexy.
Wenn sich der Benutzer über z.B. LiveID angemeldet hat, dann wird nach erfolgreicher Authentifizierung ein Benutzerkonto angelegt oder aber man kann diesen Login mit einem existierenden DNN-Benutzerkonto verknüpfen. In der Datenbank gibt es dafür die Tabelle: UserAuthentication
Bei der Suche nach Performancemessungen für ein .NET Projekt, habe ich ich folgende interessante(s) Seite / Projekt gefunden:
ProfileSharp
Bis jetzt nur kurz getestet, scheint es aber ein gute Lösung zu sein um:
- Eine Speicheranalyse durchzuführen (z.B. Memoryleaks)
- Wo welche Rechenleistung benötigt wird
Besonders interessant ist, dass der Profiler keinerlei Veränderungen am SourceCode benötigt - Bestandteile des Profilers müssen also nicht in das Projekt / Assembly k(c)ompiliert werden. Er läßt sich einfach von außen anfügen
Das Produkt ist OpenSource und steht damit jedem zur Verfügung. Ob bei dem Funktionsumfang / Leistung mit kommerzielle Produkten aufnehmen kann werd ich sehen.
Wenn man eine Anwendung nur einmal durch den Anwender starten lassen möchte, dann ist das mit der Hilfe von einem erzeugten Mutex sehr einfach zu realisieren.
Nur ein paar Zeilen Quellcode sind dafür in der Main() Methode notwendig. Wie immer ist der Beispiel-Code in .NET C#.
bool createdNew; ///Einen neuen Mutex erzeugen, damit die Anwendung nur einmal gestartet werden kann. System.Threading.Mutex appMutex = new System.Threading.Mutex(true, Application.ProductName, out createdNew); ///Wenn die Erzeugung erfolgreich war if (createdNew) { ///... dann kann die Anwendung ausgeführt werden LogIn frmLogIn = new LogIn(); Application.Run(frmLogIn);
if (frmLogIn.DialogResult == DialogResult.OK) Application.Run(new MainForm());
// den Mutex wieder frei geben appMutex.ReleaseMutex(); } else { ///Wenn die Anwendung schon ausgeführt wird -> Hinweis-Dialog string msg = String.Format("Das Programm \"{0}\" wurde bereits gestartet!", Application.ProductName); MessageBox.Show(msg, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information); }
Das Core-Team von DotNetNuke hat in den letzten Versionen schon einiges an der Usability verbessert. Darunter gehört z.B. die Vererbung von Seiten-Rechten innerhalb der Seitenstruktur.
In vielen Projekten höre ich aber immer wieder, dass das ControlPanel (dort wo z.B. die Module ausgewählt werden) nicht flexibel genug ist und es Vorteilhaft wäre, wenn man anhand der DotNetNuke spez. Rollen die Funktionen ganz gezielt freischalten kann. Somit könnte man bestimmten Rollen ganz gezielt lediglich ein paar Module zur Verfügung stellen, die diese für ihre tägliche Arbeit benötigen. Der Vorteil liegt ganz klar auf der Hand: Die Komplexität für die Redaktuere wird reduziert. In vielen Fällen werden ja wirklich nur ganz wenige Module für die normale Arbeite benötigt (z.B.Text/HTML, Links, Images).
Seit ein paar Monaten verfolge ich eine Projekt, dass das DotNetNuke ControlPanel ersetzt (oder viel mehr eine Alternative bereit stellt). Mit diesem ControlPanel ist es nun endlich möglich die Berechtigungen innerhalb des Controlpanels sehr gezielt zu vergeben.
Hier kann man das Modul downloaden
Leider gibt es keine SourceCode Version von diesem Modul.
In der letzten Zeit findet man im Web immer wieder Popup-Fenster die wie folgt aussehen:

Die Umsetzung erfolgt via JavaScript und CSS und stellt kein großes Geheimnis dar. Wer sich allerdings trotzdem nicht die Mühe machen möchte (und niemand möchte wirklich etwas erarbeiten, was es schon gibt), für den habe ich hier einen tollen Link: http://orangoo.com/labs/GreyBox/. Auf dieser Seite gibt es eine Komponente (JavaScript) die einem bei der Umsetzung unterstützt.
Die Vorteile:
- Es wird nicht durch die PopUp-Blocker verhindet, da es ja kein neues Fenster ist
- Mit nur 22kb ist das Script recht klein
- Wird schon auf viele Websites eingesetzt und kann als stabil betrachtet werden
Gerade habe ich ein kostenloses eBook zum Thema Coding Guidlines für C# und VB.NET gefunden und möchte darauf aufmerksam machen.
Den Download gibt es direkt unter submain.com
Das eBook hat folgende Themen:
- Naming Guidelines
- Class Member Usage Guidelines
- Guidelines for Exposing Functionality to COM
- Error Raising & Handling Guidelines
- Array Usage Guidelines
- Operator Overloading Usage Guidelines
- Guidelines for Casting Types
- Common Design Patterns
- Callback Function Usage
- Time-Out Usage
- Security in Class Libraries
- Threading Design Guidelines
- Formatting Standards
- Commenting Code
- Code Reviews
- Additional Notes for VB .NET Developers
Ebenso recht nützlich ist das Tool SmartOutline for VS2005, welches als kostenlose Version auf der Seite zur Verfügung gestellt wird. Damit wird das Handling von #region's - welche ich sehr gerne benutze - noch etwas verbessert.
Im Augenblick beschäftige ich mich mit dem DNN NavigationProvider. um für einen Kunden ein CSS basiertes Menu zur Verfügung zu stellen. Ursprünglich dachte ich eigentlich, dass man auf das Rendern des Menüs Einfluß hat und bestimmen kann, wie das Menu auszusehen hat.
Nachdem ich den Sourcecode der mitgelieferten Provider analysiert habe .. kam zunächst recht schnell die Ernüchterung. Da wird in der class DNNMenuNavigationProvider auf eine Objekt vom Typ DNNMenu zugegriffen. Doch der Sourcecode scheint davon nicht mit im Standarddownload enthalten zu sein.
Mein erster Schreck - das ich das Rendern gar nicht beeinflussen kann - ging schnell vorbei. Zum einem ist natürlich die Klasse DNNMenu in dem Downloadpaket DotNetNuke WebControls enthalten und zum anderen ist die Nutzung dieses Objektes ja gar nicht notwendig.
Jetzt werde ich mal versuchen meinen eigenen Menuprovider zu entwicklen und bin gespannt wie das klappt!
Nachdem ich eigentlich schon wieder viel zu lange nichts mehr über DNN veröffentlicht hab, möchte ich damit nun endlich wieder beginnen.
Am 29.05 (also gestern) wurde die Version 4.5.2 veröffentlicht und steht wie gewohnt unter www.dotnetnuke.com zum Download bereit.
Mittlerweile ist eine ganze Menge an neuen Features implementiert wurden und eine einzelne Aufzählung wäre mit Sicherheit zu lang(weilig). Einen sehr genauen Einblick über die Veränderungen innerhalb von DotNetNuke bekommt man wie immer in der Bug Tracker.
Soeben habe ich ein sehr interessante Projekte oder viel mehr Komponente auf codeproject gesehen und möchte meiner Umwelt diese nicht vorenthalten.
Dabei handelt es sich jeweils um sehr schön gemachte Status List entwickelt in C#. Hier ist der direkte Link zu dieser .NET Komponente .... klick :)
Dazu passend gibt es auch noch ein Status Label (wohl in VB.NET) ... klick
Suchmaschinen wie www.google.de oder www.live.de sind für alle Entwickler - ob .NET, PHP, Delphi, etc. - ein wertvolles Werkzeug um schnell Antworten und Lösungen bei Problemem zu finden.
Das größte Problem dabei ist aber meist, dass man nicht nur Suchergebnisse bekommt dich sich auch wirklich mit .NET befassen und somit wird die Recherche unnötig erschwert. Dieses gehört aber der Vergangenheit an, denn Dan Appleman hat folgende Website erstellt:
http://www.searchdotnet.com/
Diese Suchmaschine basiert auf Google, allerdings werden wirklich nur .NET relevante Ergebnisse angezeigt.
Die ersten Erfahrungen mit dieer Suchmaschine waren sehr positiv!
Nachdem ich nun mein neues Notebook habe und mir ein komplett neues System aufsetzen musste - bekam ich plötzlich einen ganz seltsamen Fehler bei DotNetNuke und der Verwendung des PopUp Kalenders. Hier wurde das Datum wahlweise mal im richtigen und dann mal wieder im falschen Format zurück gegeben. Nur zur Erklärung: Das richtige Datumsformat ist für mich das deutsche (weil deutsche Anwendung) also dd.MM.yyyy aber ich bekam immer wieder folgendes m/d/yyyy.
Zunächst dachte ich daran, das die es ein Konfigurationsfehler sei bzw. ich mir irgendein englisches Servicepack installiert habe (ja, ich geben zu: Ich hab ein deutsches Betriebssystem - sorry). Aber auch nach erneuter Installation des DotNet Frameworks, war keine Besserung in sicht :(
Dann hab ich ein wenig im Forum von DNN gesucht in bin da auch recht schnell auf eine Lösung gekommen:
Wer ein ähnliches Problem hat sollte ganz einfach in der Javascript-Datei "~/js/PopupCalendar.js" folgende Zeile verändern:
anchorVal = "<A HREF=\"javascript:window.opener.calPopupSetDate(window.opener.popCalDstFld,'" + (thisMonth+1) + "/" + monthDate + "/" + thisYear + "');window.opener.closeCalPopup()\">";
zu
anchorVal = "<A HREF=\" window.opener.calPopupSetDate(window.opener.popCalDstFld,'" + constructDate(monthDate,thisMonth+1,thisYear) + "');window.opener.closeCalPopup()\">";
Durch die Verwendung von "constructDate" wird sichergestellt, dass auch auf jeden Fall das richtige Format zurück geliefert wird, wenn ein Anwender im DotNetNuke Popup Kalender darauf klickt!
In der Version 4.4.0 ist dieser Fehler laut Gemini-Report behoben ... für alle anderen installierten Version sollten diese Fix manuell vornehmen!
Mit dem RangeValidator von ASP.Net ist es nicht so ohne weiteres möglich die Länge einer Eingabe (Strings) zu überprüfen. Durch die Verwendung eines regulären Ausdrucks kann man aber trotzdem diese Überprüfung durchführen.
So sieht das dann im Code aus: <asp:RegularExpressionValidator ID="checklength" runat="server" ErrorMessage="Error: invalid length" ValidationExpression="^\w{1,10}$" />
Der Ausdruck "\~w(1,10)$" besagt das die Eingabe maximal 20 Zeichen lang sei darf.
Natürlich kann man auch die Eigenschaft MaxLength des Controls Textbox nutzen, allerdings kann man damit keinen Minimumwert überprüfen.
Wie ich schon in meinem Beitrag über den NRW Sumit 06 geschrieben haben, hat Newtelligence eine Beispielanwendung für die WCF geschrieben. Diese Anwendung wurde im Auftrag des BSI (Bundesamt für Sicherheit in der Informationstechnik) entwickelt und sollte nicht nur ein praxisorientierte Beispielanwendung sondern viel mehr die sichere Nutzung der WCF-Sicherheitsfunktionen zeigen. Die Empfehlungen umfassen neben den Hinweisen zu WCF-spezifischen Architekturen, zur sicheren Installation, Authentisierung und zur Anbindung von Datenbanken oder der Fehlerbehandlung in verteilten Systemen auch auch den Quellcode der beispielhaften WCF-Anwendung.
Die entwickelten Handlungsempfehlungen sowie die Beispielanwendung kann per E-Mail (security (at) bsi.bund.de) angefordert werden.
Ohne jetzt große Erfahrungen mit dem System iBATIS gemacht zu haben, kann ich sagen, dass mir die Vorgehensweise sehr gut gefällt! So um 2000 herum habe ich mit einem Kollegen eine ähnliche Datenbankzugriffskomponente entwickelt und sehr gute Erfahrungen damit gesammelt. Gerade das Auslagern der der SQL-Befehle bzw. die Abstrahierung der SQL-Befehle kann Vorteile haben. Damals haben wir dieses Konzept unter dem Aspekt der Datenbankunabhänigkeit implementiert und eine allgemeine Beschreibung in Form von XML auf die entsprechende Datenbank zur Laufzeit angepasst.
Freut mich doch immer wieder wenn ich Projekte sehe, die ähnliche Methode anwenden.
Mittlerweile bin ich zwar mehr der Freund vom Provider-Pattern aber der Ansatz von iBATIS kann durchaus einen Sinn ergeben! Eine weiter Diskussion erspare ich mir an dieser Stelle :)
Ach so, hier gibt es noch den Link.
Nur so am Rande: MySpace.com benutzt nicht nur ASP.NET 2.0 sondern auch iBATIS .. guckst Du hier!
Das DotNetNuke mittlerweile einen sehr großen und brauchbaren Funktionsumfang hat muss an dieser Stelle nicht weiter erwähnt werden. Bei der Implementierung alle dieser Features stand aber leider der Punkt Geschwindigkeit (Performance) nie im Mittelpunkt. Das soll nun endlich mit der kommenden Version 4.4.0 verändert werden!
Durch folgende Maßnahmen soll die Geschwindigkeit verbessert werden:
(1) Code Refactoring
(2) Optimierung und verbesserte Einsatz des Caching
(3) Assembly Management
(4) Database
(5) Compression
(6) Page State
Wer genauer wissen möchte was sich hinter den einzelnen Punkten versteckt kann das im Blogeintrag von Charles Nurse hier nachlesen.
Die Ergebnisse der ersten Tests kann man hier nachlesen!
Auf die Version 4.4.0 dürfen wir also alle sehr gespannt sein :)
Auch wenn ich bis jetzt das Thema Ajax hier wohl mehr stiefmütterlich behandelt habe, habe ich dieses immer im Fokus. Das von Microsoft entwickelte Ajax-Framework steht nun als RC zur Verfügung und kann hier runtergeladen weden.
Jetzt kann man also über einen ernsthaften Einsatz nachdenken und ich werde das Thema nun endlich angehen.
Für einen Bekannten habe ich eine DotNetNukeinstallation (4.3.6) aufgesetzt und ihn ein wenig damit spielen lassen. Dabei hat er sich auch ein wenig mit den Profileigenschaften eines Users beschäftigt und diese Modifiziert. Das finde ich doch schon sehr gut und hätte ich mir eigentlich von Anfang an gewünscht ..
Da sein Portal lediglich den deutschsprachigen Raum anspricht hat er einfach die Eigenschaft TimeZone gelöscht. Leider findet das DotNetNuke gar nicht witzig und normale Anwender konnten sich ab diesem Zeitpunkt nicht mehr anmelden. Einige Komponenten benötigen diese Profileigenschaft und es kracht ganz schön böse, falls diese nicht im Profil enthalten ist.
Also: Vorsicht beim Löschen von Profileigenschaften - lieber ausblenden:)
Schon länger wollte ich mein Notebook mal mit Windows Vista ausstatten doch irgendwie fehlte mir die Zeit. Nachdem dann letzte Nacht mein Notebook softwaretechnisch zu Bode ging, habe ich mich direkt entschlossen Windows Vista zu installieren. Im guten Glauben gesagt, getan und dachte alles wäre gut! Doch weit gefehlt... der erste Eindruck ist echt gut (ein wenig gewöhnungsbedürftig aber ich würde sagen: nicht schlecht)....
Dann habe ich meine Visual Studio 2003 installiert, was kein Problem war, nur das Starten war mir nicht vergönnt. Was soll das denn ????
Eigentlich bin ich davon ausgegangen, dass Microsoft die meist verwendeten Anwendungen (Visual Studio 2003 / MS-SQL Server 2000, usw) unterstützt ... diese Hoffnung ist aber gerade wie eine Seifenblase geplatzt! Normalerweise bin ich nicht contra-microsoft aber das ist ja wohl komplett am Thema vorbei!
Sogar Visual Studio 2005 läuft nur nach einem ServicePack - und selbst dann gibt es wohl noch ein paar Probleme (mehr als unter XP). Super, toller Start in ein neues Betriebssystemzeitalter.... jetzt geht es wieder zum good, old Windowx XP - bis all meine Anwendung und Tools unter .NET 2.0 (3.0) laufen.
An dieser Stelle sage ich : Vielen Dank für nichts!
P.S.: Vielleicht hätten wir alle bei VB 6 bleiben sollen, denn das wird unter Vista supportet *mahlzeit*
Seit gestern gibt es die aktuelle Version von DotNetNuke auf der offiziellen Downloadseite zur Verfügung. Neben einigen Fehlern, Sicherheitslücken und Peformanceoptimierung wurde auch mal die Datensyncronisation verbessert. Genaue Informationen gibt es wie immer hier.
Die Deutsche Übersetzung findet man bei http://www.deutschnetnuke.de/
"Konflikt der Sortierung für die equal to-Operation kann nicht aufgeloest werden."
Was will der von mir???? Nach dem Umzug einer DotNetNuke - Site auf eine anderen Server bekam ich plötzlich im Log Viewer die Fehlermedlung
DotNetNuke.Services.Exceptions.ModuleLoadException: Konflikt der Sortierung für die equal to-Operation kann nicht aufgelöst werden. ---> System.Data.SqlClient.SqlException: Konflikt der Sortierung für die equal to-Operation kann nicht aufgelöst werden. at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior) at Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteReader(SqlConnection connection, SqlTransaction transaction, CommandType commandType, String commandText, SqlParameter[] commandParameters, SqlConnectionOwnership connectionOwnership) at Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteReader(String connectionString, CommandType commandType, String commandText, SqlParameter[] commandParameters) at Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteReader(String connectionString, String spName, Object[] parameterValues) at DotNetNuke.Services.Log.EventLog.DBLoggingProvider.Data.SqlDataProvider.GetLog(Int32 PageSize, Int32 PageIndex) at DotNetNuke.Services.Log.EventLog.DBLoggingProvider.DBLoggingProvider.GetLog(Int32 PageSize, Int32 PageIndex, Int32& TotalRecords) at DotNetNuke.Services.Log.EventLog.LogController.GetLog(Int32 PageSize, Int32 PageIndex, Int32& TotalRecords) at DotNetNuke.Modules.Admin.Log.LogViewer.BindData() at DotNetNuke.Modules.Admin.Log.LogViewer.Page_Load(Object sender, EventArgs e) --- Ende der internen Ausnahmestapelüberwachung ---
Nach ein wenig Forschung war die Lösung schnell gefunden. Die SP muss ein wenig verändert werden, damit der Fehler nicht mehr auftritt.
Die Stored Procedure "GetEventLog" muss von
CREATE TABLE #PageIndex ( IndexID int IDENTITY (1, 1) NOT NULL, LogGUID varchar(36) )
auf CREATE TABLE #PageIndex ( IndexID int IDENTITY (1, 1) NOT NULL, LogGUID varchar(36) COLLATE database_default )
geändert werden. Dann ist wieder alles im Lot!
Ich möchte jetzt hier gar keine Diskussion lostretten die über das Solpart-Menu herzieht. Fakt ist auf jeden Fall:
- Das Anpassen des Menü via CSS kann einem wirklich graue Haare bereiten
- Die Größe des Menü (bezogen auf die HTML Datei) ist sehr groß
- Die Suchmaschinenfreundlichkeit ist fast nicht gegeben
Aus diesen Gründen habe ich ein kleines niedliches CSS-Menu gebaut das mit HTML Aufzählungen, CSS und wirklichen Links (!) arbeitet.
Es ist noch kein perfektes Menu aber für meine derzeitigen Einsatzbereich wirklich ausreichend. Ein paar Erweiterungen und Optimierungen müssen da in Zukunft noch implementiert werden. Aber wie bei jedem Projekt gibt es auch hier mal eine Version 1.0.
Da ich sehr gerne und eigentlich fast alle DotNetNuke Module in C# entwickel ist auch dieses Modul ist c# geschrieben.
Die Einbindung in ein Skin ist relativ simple! Einfach folgendes in das Skin aufnehmen:
<%@ Register TagPrefix="gwc" Namespace="GaliNeo.Modules.Framework" Assembly="GaliNeoMenu" %>
und dann an der Stelle wo das Menü erscheinen soll:
<gwc:GaliNeoMenu runat="server" id="TestMenu"></gwc:GaliNeoMenu>
Natürlich läst sich damit so ziemlich jede Menü darstellen das sich mit den HTML Tags UL und CSS formatieren läßt. Hier ist es zunächst ein klassisches Drop-Down Menü....
Hier der Download des Source-Codes:GaliNeo.DotNetNukeMenu (1.0.0.0).zip (7,96 KB)
Ja ja ... i know. Wochenlang habe ich mein Blog vernachläßigt und jetzt jagt ein Beitrag den anderen Aber irgendwie habe ich mir heute ein wenig Zeit genommen um durch das www zu surfen.
Hier ist noch eine Seite, die man keinen DNN Skin Designe vorenthalten sollte:
http://www.xhtmlskins.com/
Auf dieser Seite geht es um die Erstellung von DotNetNuke Skins ohne Tabellen. Total sexy :)
Hier ein paar Blogbeträge zum Thema Barcodes und wie man diese unter DotNet erzeugen kann ohne 3rd-party Komponenten:
Letztes Jahr habe ich folgenden Blog-Eintrag verfasst. Darum ging es, wie man ein HTML-Form innerhalb von .NET simulieren kann.
Jetzt ist mir gerade aufgefallen, dass der Sourcecode der ausführenden Klasse dafür fehlt. Natürlich ist das der spannende und entscheidene Part für das Post der HTML-Form. Das möchte ich natürlich nicht so stehen lassen und hier kommt der fehlende Part!
using System; using System.Net; using System.Web; using System.IO; using System.Text ;
namespace GaliNeo.Framework { public class RemotePost { #region Private Members private System.Collections.Specialized.NameValueCollection Inputs = null ; private string _sUrl = "" ;
#endregion public RemotePost() { // // TODO: Fügen Sie hier die Konstruktorlogik hinzu // Inputs = new System.Collections.Specialized.NameValueCollection() ; }
#region Public Methods
public void Add(string sName, double dValue) { this.Add(sName, dValue.ToString()) ; }
public void Add(string sName,int iValue) { this.Add(sName, iValue.ToString() ) ; } public void Add(string sName,string sValue) { Inputs.Add(sName,sValue) ; }
public string Url { get { return _sUrl ; } set { _sUrl = value ; } } public string Send() { string sPostData = "" ;
Uri sUri = new Uri(this.Url) ; //Wird für evtl. SSL - Verbindungen benötigt System.Net.ServicePointManager.CertificatePolicy = new trustedCertificatePolicy();
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(sUri);
//User-Agent request.UserAgent = "GaliNeo OnlineStore" ;
request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; //Zusammensetzen der Daten für die Übermittlung sPostData = GetContentToPost() ; request.ContentLength = sPostData.Length ;
Stream writeStream = request.GetRequestStream(); //Encoding im UTF-8 Format um kompatible zu sein //UTF8Encoding encoding = new UTF8Encoding(); //UFT-8 funktioniert unter ASP.NET nicht :( System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding() ; byte[] bytes = encoding.GetBytes(sPostData); writeStream.Write(bytes, 0, bytes.Length); writeStream.Close();
HttpWebResponse response = (HttpWebResponse) request.GetResponse(); //Überprüft den HTTP-Statuscode if (response.StatusCode != HttpStatusCode.OK) { return "N,-1, HTTPStatuscode:" +response.StatusCode.ToString() ; }
Stream responseStream = response.GetResponseStream(); StreamReader readStream = new StreamReader (responseStream, Encoding.UTF8); return readStream.ReadToEnd(); }
public string GetContentToPost() { string sReturn = "" ;
for(int i=0; i< Inputs.Keys.Count;i++) { if (sReturn.Length == 0) { sReturn = Inputs.Keys[i] + "=" + Inputs[Inputs.Keys[i]] ; } else { sReturn += "&" + Inputs.Keys[i] + "=" + Inputs[Inputs.Keys[i]] ; }// if (sPostData.Length == 0)
}//for(int i=0; i< Inputs.Keys.Count;i++)
return sReturn ;
}
#endregion
} }
Wer schon mal HTML-E-Mails verschickt hat kommt wohl kaum um das Problem herum, dass man auch Bilder dieser E-Mail hinzufügen möchte. Der erste und einfachste Weg ist, diese einfach auf einem Server abzulegen und dann auf diesen zu verweisen. Was ist aber wenn der Anwender keine Internetverbindung hat, der Server bzw. das Bild nicht mehr erreichbar ist? Dann sehen diese E-Mails meist sehr unschön aus.
Gerade habe ich einen netten Artikel gefunden, der Beschreibt, wie man ein Bild als E-Mailanhang mitschickt und wie man die Verbindung zwischen Bild und Anhang herstellen kann.
Hier einmal die Kurzfassung:
<IMG height=68 src="cid:015024716@24012006-255A" width=140 align=top border=0>
Die Sourceanweisung mit dem Wert "cid:015024716@24012006-255A" ist hier das interessante. Die RFC-Spezi. besagt das jeder E-Mailanhang eine eindeutige Id bekommt.
Der benötigte Sourcecode zum Versand der E-Mail:
'Zu erst mal die Imports die benötigt werden Imports System.Net.Mail Imports System.Net.Mime
Public Sub SendMail()
Dim objMail As New MailMessage Dim objSender As New MailAddress("absender@server.de") Dim objSmtpClient As New SmtpClient("smtp.server.de:8881") Dim objEmpfaenger As New MailAddress("empfaenger@server.de")
objMail.To.Add(objEmpfaenger) objMail.From = objSender objMail.Subject = "Betreff der Mail"
'Damit das ganze auch funktioniert muss man angeben, 'das man die Mail im HTML-Format verschicken möchte objMail.IsBodyHtml = True
'So jetzt zum spannenden Teil, das Bild als Attachment anfügen Dim objFootImage As New Attachment(Server.MapPath("LOGO.gif"), _ MediaTypeNames.Image.Gif) objFootImage.ContentId = "01" objFootImage.ContentDisposition.Inline = True objFootImage.TransferEncoding = TransferEncoding.Base64 objMail.Attachments.Add(objFootImage)
'Und so wird es anschließend verwendet objMail.Body = "<img src=""cid:01"" border=0 height=68 width=140>"
'Jetzt nurnoch die Mail verschicken und fertig objSmtpClient.Send(objMail) End Sub
Eine ausführliche Erklärung des ganzen gibt es auf dieser Seite
Ich habe gerade eine coole Seite über Threading in .NET 2.0 gefunden, die auch viele Beispiele in C# bietet.
http://www.albahari.com/threading/
Zudem gibt es (derzeit links unten) einen PDF, das nun auf meinem "muss ich unbedingt mal komplett Lesen" Stappel liegt 
Auf CodePlex wird von Microsoft ein Projekt mit dem Namen Phalanger gehostet. Phalager soll einen PHP-Compiler anzubieten, der es ermöglicht, PHP-Skripts ohne Modifikation auf .NET zu kompilieren. Dabei erzeugt der Compilier aus PHP-Skipts MSIL (Microsoft Intermediate Language). Ausprobiert habe ich es selber noch nicht, allerdings finde ich den Ansatz sehr interessant!
Hier der direkte Link zum Projekt auf CodePlex
Letzte Woche Donnerstag war ich auf dem diesjährigen NRW Sumit veranstaltet von JustCommunity e.V.. Es war eine wirklich klasse Veranstaltung, auf der man eine ganze Menge geboten bekommen hat. Es gab sehr viele interessante Vorträge und die eine besser Auswahl an Dozenten kann man wohl kaum treffen. Nur schade war das Christian Weyer absagen musste und damit der Vortrag über die WCF ausgefallen ist. Es war eine gute Gelegenheit sich mit Kollegen auszutauschen und ein paar Anregungen mitzunehmen.
Es wurden aber nicht nur Vorträge zum Thema "Mircosoft" angeboten auch die PHP- und Linuxwelt waren mit Referenten vertreten. Also für jeden Geschmack gab es das passende Angebot.
Besonders gespant war ich auf den letzten Vortrag über "Indigo & SOA in the real World", in dem Daniel Fisher und Michael "Security" Willers aus einem Projekt für das BSI berichteten. Ziel war es wohl Indigo (WCF) auf Sicherheitsmerkmale zu überprüfen. Nun und auf der ersten Folie stand dann plötzlich Proseware :) ... die Anwendung lebt also doch noch. Ich bin leider nicht dazu gekommen nachzufragen ob die Anwendung komplett neugeschrieben wurde oder aber ob es die Basis von Clemens ist. Leider hat Proseware ja nie eine Freigabe von Microsoft erhalten :( aber diese Version wird wohl zum Ende des Jahres erhältlich sein ... ich denke auf diese Anwendung darf man sich sehr freuen!
Leider konnte ich nicht alle Vorträge besuchen da immer vier Tracks parallel liefen und das von 10:00Uhr Uhr bis Abends 20:30Uhr (!). Aufgrund der Länge und des doch sehr warmen Wetters waren wohl alle am Abend ziemlich platt und müde, was bei der anschließende Party mit 50 Liter Freibier aber keinen größeren Schaden anrichtete.
Ein großes Dankeschön geht an dieser Stelle an die beiden Hauptorganisatoren Daniel Fisher und Stephan Oetzel ... ich freue mich sehr auf den NRW Summit 07 :)
Die letzten Monate war es um DotNetNuke ja doch recht ruhig geworden. Mittlerweile kommt aber wieder Leben in den Releasezyklus :) Vor wenigen Tagen wurde die Version 3.3.3 veröffentlich, die als Final Release bezeichnet wird.
Hier ist ein Auszug aus den Änderungen (die Orginalfassung findet man unter dotnenuke.com):
Membership Management CAPTCHA - eine bekannte Technologie, die mehr Sicherheit bei der Anmeldung verspricht. In einem Bild werden Zahlen und oder Buchstaben angezeigt, die der Benutzer bei der Anmeldung eingegben muss. Durch die Darstellung als Bild es es dann nicht mehr so ohne weiteres möglich eine brute force Attacke durchzuführen. Login Redirect - Nach der Anmeldung kann man die User zu einer definierten Seite weiterleiten Password Generation - Als Administrator kann man nun automatisier ein Passwort für einen Anwender verwegeben. Public Registration - Beim diesem Anmeldetyp wird nun auch eine E-Mail an den Benutzer geschickt - damit kann man den Mißbrauch von Daten vorbeugen. Profile Change Notification - Anwender werde über Änderungen in Ihrem Profil per E-Mail informiert. User Account Creation Notification - Wenn ein Administrator ein Benutzerkonto anlegt, dann können nun die Daten an den entsprechenden Benutzer verschickt werden. Force Profile Update - Der Benutzer kann dazu "gezwungen" werden, nach einem Login sein Profil u verändern. Force Password Change - Bietet die Möglichkeit das der Anwender sein Passwort erneuern muss. Password Complexity - Der Aufbau und die Komplexität der Passwörter lassen sich definieren. Preserve Login Parameters - Wenn ein Benutzer zur Anmeldung geleitet wird, dann wird nun die Herkunftsurl ausgelesen und gespeichert, damit anschließend dahin zurück geleitet werden kann. Automated Verified Registration URL - Der Benutzer bekommt per E-Mail eine URL und sobald er diese aufruft wird das Konto freigeschaltet. User Lockout Notification - Wen ein Benutzerkonto gesperrt wird (durch die falsche Eingabe vom Passwort), bekommt der Administrator darüber eine E-Mail.
Role Management Effective Date - Ab wann soll eine Rolle gültig sein. Role Groups - Rollen können nun zu Gruppen zusammengefasst werden.
Usability Rich Text Editor - Nun können Verlinkungen zu Seiten im Poral direkt angelegt werden. Newsletter - Die Abenderadresse kann definiert werden.
Framework AccessDeniedURL - Hierfür kan nu eine Seite definiert werden.
Performance Module Settings - Seiten und Moduleinstellungen werden nun gecached :).
Module Definitions/Installer Module Definitions - Die Moduledefinition kann nun direkt durch eine *.dnn Datei angelegt werden, ohne eine Zip-Datei hochzuladen.
Other SMTP Settings - Die Portnumber kann angepasst werden New Modules - Store, Forums, Blogs, Gallery sind nun Bestandteil der aktuellen Version.
In der Mittagspause noch mit einem Bekannte über DNN diskutiert und das es in der letzten Zeit doch recht still geworden ist .... musste ich gerade feststellen das das Core-Team von DotNetNuke heute das neue Release 3.3.0 zum Download frei gegeben hat.
Leider komme ich in den nächsten nicht dazu diese Version zu testen aber in den Foren gibt es dazu bestimmt jede Menge zu lesen - oder auch nicht, wenn alles ohne Probleme verläuft. Es bleibt aber dabei: Zuerst die Installationsanweisung von DotNetNuke lesen und auf jeden Fall eine komplette Datensicherung von Datenbank und Dateisystem durchführen.
Die deutsche Übersetzung gibt es wie immer unter Sebastian Leupold.
Habe gerade eine OpenSource Library/Komponente entdeckt, die den Zugrif auf die Messanagerplattform von MSN ermöglicht. In manchen Anwendungsszenarien macht es durchaus Sinn, einen Messanger als Kommunikationsweg einzusetzen z.B. bei kritischen Fehlermeldungen, Meldungen das ein asyncroner langer Prozess beendet ist, usw.
Wer dafür den MSN Messanger nutzen möchte aber die Anbindung nicht selber programmieren mag, sollte sich folgende Library anschauen: http://www.xihsolutions.net/dotmsn/index.html
Gerade habe ich eine doch sehr cooles .NET Opensource Projekt auf sourcefroge.net gefunden. Dabei handelt es sich um eine in C# geschriebene Komponenten die eine Dockingfunktionalität bietet. Vorlage war dabei wohl das Visual Studio.net 2005.
Für so manche .NET Windows Anwendung dürfte das eine wirkliche Bereichung sein. Hier geht es zu der Komponente: Link
Wer mal "eben" ein Regex-Pattern erstellen möchte und dieses auch direkt testen will, kann ein kleines Online-Tool dafür nutzen. Hier der Link
Ich kann es ja kaum glauben aber bei dem mächtigen Framework von .Net wird es echt kompliziert eine DateTime Wert von GMT in PST zu konvertieren. Habe gerade ein paar lustige Stunden damit verbraucht eine dieses einigermaßen sauber zu implementieren und hier meine Lösung:
Basis für meine Lösung ist eine Klasse von Clemens Vasters und seiner Blogengine dasblog.net. Dort gibt es im Projekt "newtelligence.DasBlog.Util.csproj" die Klasse "TimeZones.cs". Die nötigen Informationen für eine Konvertierung wird hier allerdings in einer XML Datei gespeichert. Da ich derzeit allerdings nur eine konvertierung nach PST brauch habe ich die XML Datei ignoriert und setze die Daten manuell in einer Klasse.
/// <summary> /// Liefert verschiedne Zeiten auf der Welt zurücl /// </summary> public class TimeZoneConverter {
/// <summary> /// (GMT-08:00) Pacific Time (US & Canada); Tijuana /// Pacific Daylight Time /// </summary> /// <returns>DateTime of Pacific Daylight Time</returns> public static DateTime GetCurrentPST() { return DateTime2PST(DateTime.Now) ; }
/// <summary> /// (GMT-08:00) Pacific Time (US & Canada); Tijuana /// Pacific Daylight Time /// </summary> /// <returns>DateTime of Pacific Daylight Time</returns> public static DateTime DateTime2PST(DateTime dtDate) {
WindowsTZI pstTZI = new WindowsTZI(); pstTZI.bias = 480; pstTZI.daylightBias = -60; pstTZI.standardBias = 0; WindowsSystemTime standardDate = new WindowsSystemTime(); standardDate.year = 0; standardDate.month = 10; standardDate.day = 5; standardDate.dayOfWeek = 0; standardDate.hour = 2; standardDate.minute = 0; standardDate.second = 0; standardDate.milliseconds = 0;
WindowsSystemTime daylightDate = new WindowsSystemTime(); daylightDate.year = 0; daylightDate.month = 4; daylightDate.day = 1; daylightDate.dayOfWeek = 0; daylightDate.hour = 2; daylightDate.minute = 0; daylightDate.second = 0; daylightDate.milliseconds = 0;
pstTZI.standardDate = standardDate; pstTZI.daylightDate = daylightDate;
WindowsTimeZone tz = new WindowsTimeZone(); tz.WinTZI = pstTZI; return tz.ToLocalTime ( dtDate.ToUniversalTime() ) ;
}
}
Wer das ganze etwas dynamischer haben möchte schaut sich am beste die Klasse vom Clemens an ...
Ich brauchte diese Funktion für die Google-Adwords-API, diese erwatet nämlich das Datum im PST Format.
Gerade habe ich einen interessanten Artikel gefunden der zeigt, wie man einen Parameter aus der Querystringauflistung entfernen kann.
Public Sub RemoveQueryString(ByVal Req As HttpRequest, ByVal strKeyToDel As String, ByVal http_Context As HttpContext) Dim nvc As System.Collections.Specialized.NameValueCollection = New System.Collections.Specialized.NameValueCollection(Req.QueryString) Dim sPage As String = Req.ServerVariables("SERVER_NAME") & Req.ServerVariables("SCRIPT_NAME") nvc.Remove(strKeyToDel)
Dim strNewURL As String = Req.Path Dim sSeparator As String = "?" Dim sKey As String For Each sKey In nvc If sKey <> Nothing Then Dim sValues As String() = nvc.GetValues(sKey) Dim sValue As String For Each sValue In sValues If sValue <> Nothing Then strNewURL &= sSeparator strNewURL &= sKey & "=" & sValue sSeparator = "&" End If Next End If Next If nvc.Keys.Count < 1 Then strNewURL &= "?" End If http_Context.Current.RewritePath(strNewURL) End Sub
Gefunden habe ich den Code unter http://www.codeproject.com
Eines meiner größten Probleme - oder sagen wir lieber Sorgen - war bisher, dass DNN keine Transaktionen unterstützt. Es gibt doch immer wieder mal Business-Cases wo man transaktionsicher Daten verarbeiten möchte. Ein typischens Beispiel wäre z.B. eine Online-Shop, wenn es um die Bestellung und gleichzeitige Zahlungsabwicklung geht.
Da DotNetNuke in vermutlich in vielen Fällen auf einem Windows 2003 Server betrieben wird, ist die komplette Umgebung schon vorhanden um die Abläufe transaktionssicher zu gestalten. Das Stichwort ist hier "Services without Components". Der Begriff "Services without Components" steht für die Nutzung von COM+-Dienste in .NET-Anwendung ohne Registrierung als Serviced Component (COM+-Anwendung).
Klassen: .ServiceConfig and System.EnterpriseServices.ServiceDomain
Das folgende Beispiel zeigt eine ganz einfache Implementierung innerhalb einer Methode:
//Hier wird mit einem Transaktionskontext gearbeitet, //damit das Handling einfacher wird ServiceConfig sc = new ServiceConfig(); sc.Transaction = TransactionOption.RequiresNew ; ServiceDomain.Enter ( sc ) ;
try { //mach was .... ContextUtil.SetComplete() ;
} catch (Exception exc) { ContextUtil.SetAbort() ; throw exc ; } finally { ServiceDomain.Leave(); }
Seit einigen Tagen existiert ein eigenes Informations-Portal für IT-Architekten (www.architectsconnection.de). Dort stehen sehr viele architekturrelevanten Ressourcen – Fachartikel, Kommentare, Web- und PodCasts, Vorträge, Event-Termine u.v.m zur Verfügung und soll bei den täglichen Aufgaben helfen und unterstützen.
Der Gedanke des Portals ist "Service von Architekten für Architekten". Schauen wir mal wie sich dieses Microsoft Portal entwickelt.
Bevor ich aber mit .NET 2.0 so richtig loslege hier noch ein kleiner Codebeitrag. Man hat ja immer wieder die Anforderung Daten in CSV zu exportieren (im Zeitalter von XML für mich unverständlich aber gut ). Dafür veröffentliche ich jetzt das fünftausenste Code-Beispiel.
Zunächst habe ich eine allgemeine Basisklasse geschrieben, die auch für weiter Exportformate genutzt werden kann:
using System; using System.Data; using System.Web; using System.Text; using System.IO;
namespace GaliNeo.Framework { /// <summary> /// Zusammenfassung für BaseConverter. /// </summary> public abstract class BaseConverter { public BaseConverter() { }
/// <summary> /// Export DataTable to http stream /// </summary> /// <param name="oDataTable"></param> /// <param name="response"></param> /// <param name="sFileName"></param> public void ExportToResponseStream(DataTable oDataTable, System.Web.HttpResponse response, string sFileName) { response.Clear() ; response.ClearHeaders(); response.ClearContent(); response.Buffer = true; //Very importent because "ü", "ä", usw....
response.ContentEncoding = System.Text.Encoding.Default ; response.ContentType = GetHTTPContentType() ; response.AppendHeader("content-disposition", "attachment; filename=" + HttpUtility.UrlEncode(sFileName, System.Text.Encoding.UTF8)) ;
response.Write( ConvertDataTable(oDataTable).ToString() ) ; //close http response response.End();
}
/// <summary> /// Export datatable to file /// </summary> /// <param name="oDataTable"></param> /// <param name="sFileName"></param> /// <returns></returns> public bool ExportToFile(DataTable oDataTable, string sFileName ) { try { string fullpath = System.IO.Path.GetFullPath( sFileName ) ; if (System.IO.Directory.Exists ( fullpath )) { System.IO.Directory.CreateDirectory( fullpath ) ; }
StreamWriter SW; SW=File.CreateText(sFileName); SW.WriteLine(ConvertDataTable(oDataTable).ToString()); SW.Close(); return true ; } catch { return false ; }
}
protected abstract StringBuilder ConvertDataTable(DataTable oDataTable) ; protected abstract string GetHTTPContentType() ;
} }
Die Klasse ermöglicht es eine Stream entweder auf Festplatte zu schreiben oder aber in den HTTP Responsestream.
Die passende CSV-Klasse ist relativ simple und kein wirkliches Geheimnis:
using System; using System.Data; using System.IO; using System.Text;
namespace GaliNeo.Framework { /// <summary> /// Summary description for CSVConvertor. /// </summary> public class CSVConverter : BaseConverter {
protected override string GetHTTPContentType() { return "text/csv"; }
/// <summary> /// To generate CSV file. /// </summary> /// <param name="oDataTable"></param> /// <param name="directoryPath"></param> /// <param name="fileName"></param> /// <returns></returns> protected override StringBuilder ConvertDataTable(DataTable oDataTable) {
StringBuilder oStringBuilder = new StringBuilder();
// Start, Creating column header
foreach(DataColumn oDataColumn in oDataTable.Columns) { oStringBuilder.Append(oDataColumn.ColumnName + ","); oStringBuilder.Append( System.Environment.NewLine ) ; }
//End, Creating column header //Start, Creating rows
foreach(DataRow oDataRow in oDataTable.Rows) { foreach(DataColumn oDataColumn in oDataTable.Columns) { oStringBuilder.Append(oDataRow[oDataColumn.ColumnName] + ","); }
oStringBuilder.Append( System.Environment.NewLine ) ; }
//End, Creating rows
return oStringBuilder;
} } }
Fertig!
Heute hat das Coreteam von DotNetNuke ein weiters Modul frei gegeben. Diesmal handelt es sich um ein Modul das eine Shopfunktionalität abbildet. Bei der Installation sollte man darauf achten das man nicht das Module "Categories" von efficionconsulting installiert hat, denn sonst kommt es zu Konflikten bei der Namensgebung. Diese Hürde einmal genommen ist die weiter Installation kein Problem.
Die Funktionalität ist ziemlich Low-Level und an einige Stellen gibt es noch Fehlermeldungen (z.B. bei den Einstellungen). Es gibt aber ein paar ganz gute Ansätze und ich denke das im Laufe der Zeit dieses Modul noch an Funktionsumfang zunimmt. In den nächsten Tagen werde ich wohl auch noch mal in den Source reinschauen ... so einfach aus neugier.
Für mich selber ist dieses Modul eher uninteressant, da mein Shop so langsam die Version 1.0 ereicht hat; auch wenn er laut Zeitplanung schon längst fertig sein sollte .. na ja es kommt halt immer anders als man denkt. Mittlerweile ist die Featureliste schon sehr lang - erspare mir diese aber jetzt. Eines der wichtigsten Merkmale ist aber wohl, dass alle öffentlichen Bereiche über Templates pro Portal dynamisch anpassbar sind. Ebenso ist der Bestellprozess über eine XML Workflowbeschreibung komplett frei definierbar. Anpassbarkeit und Konfigurierbakeit ist bei der Implementierung sehr wichtig gewesen. Das erste Projekt wird vermutlich nächste Woche live gehen aber dann nur für eine bestimme Gruppe von Personen. Wer trotzdem mal mehr darüber wissen möchte, kann sich ja bei mir melden. Was mit dem Shop passiert ist noch nicht ganz klar.
Eines der doch besten Argumente für die Linux- bzw. PHP-Welt im Webumfeld waren bis vor einiger Zeit immer noch die doch sehr teuren Hostingpakete von Windowsbetriebssystemen. Mittlerweile fallen die Preise ständig und sind auf einem Niveau, wie es auch im Linuxumfeld anzutreffen ist.
Das ist besonders für Freunde und Fans von DotNetNuke interessant! Es gibt zwar auch einige Anbieter die ein DotNetNuke Hosting für z.B. 10€ anbiete aber wer gerne Kontrolle über seine System hat sollte sich überlegen einen eigenen Server zu mieten.
Nicht nur das man dort der eigene Administrator ist .. man ist bei vielen Punkten nicht auf den Support seinen Providers angewiesen.
Ganz davon abgesehen, dass man auch weiter Anwendungen auf seinem Server unterbringen kann.
Ich habe nun schon seit über einem Jahr einen Server bei Strato stehen und bin mit dem Service sehr zufrieden. Wer also ein paar Euro mehr ausgibt bekommt dafür auch deutlich mehr geboten. Ich persönlich möchte das nicht mehr missen. Immerhin läuft auch mein Block darüber und ein paar weitere Anwendungen.
Weil ich das Angebot sehr gut finde habe ich oben mal einen Banner eingebaut - wer also einen Buchen will .. einfach klicken :)
Am 15 Januar hat Locopon einen neuen alternativen DotNetNuke Provider für den WYSIWYG Editor FCKEditor zum download bereitgestellt. Zu finden under diesem Link....
Dieser Provider ist ein VB.NET OpenSource Projekt (und damit kostenlos) und stellt eine echte Alternative zur FreeTextBox dar - wenn nicht sogar eine besser Lösung. Die einzelnen Features werden auf der Website näher erklärt.....
Wer eine deutsche Übersetzung sucht ist auf DeutschnetNuke gut aufgehoben.
Ich wollte gerade eine Modul etwas benutzerfreundlicher gestalten und bei einem Link im ToolTip einen Kommantar / Vorschau anzeigen. Der Text der im ToolTip angezeigt werden soll liegt im HTML Format vor. Das macht die Ansicht schwer, da im ToolTip keine HTML-Zeichen verarbeitet werden.
Habe mir dann einfach ein paar Regular Expressions geschrieben, die mir helfen sollen den Text vom HTML zu befreien.
string sHTMLToolTip = ..... //HTML Message
sHTMLToolTip = Regex.Replace( sHTMLToolTip, "<(br|p)>", System.Environment.NewLine , RegexOptions.IgnoreCase | RegexOptions.Multiline);
sHTMLToolTip = Regex.Replace( sHTMLToolTip, "<(.|\n)+?>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
Ich glaube auf die RegEx muss ich nicht näher eingehen 
Habe gerade bei The Code Project ein ziemlich cooles ASP.NET Control gefunden. Damit kann man einen Kalender genau wie in Outlook darstellen:
http://www.codeproject.com/useritems/daypilot.asp
Habe das Control selber noch nicht ausprobiert aber die Demo sieht schon mal sehr vielversprechend aus! Das Beste zu Schluß: Es ist ein OpenSource Projekt 
Eine kleine Änderung habe ich in der Templateengine vorgenommen: Das Control skin aus der der Methode LoadSkin() habe ich nicht nur für diese Methode zur Verfügung gestellt sondern daraus eine protected Variable innerhalb der Klasse gemacht. Somit kann nun die abgeleitete Klasse immer darauf zugreifen und der "Umweg" über sender (siehe Part 2) kann geändert werden.
Ich brauchte das gerade für eine Hilfsmethode die ich nicht nur innerhalb der Methode InitializeSkin aufrufen möchte.
Keine Ahnung warum ich das nicht direkt so gemacht habe!
In meinem ersten Eintrag habe ich beschrieben, wie man eine Grundlage für templategesteuerte DotNetNuke Module erstellen kann.
Heute möchte ich kurz darauf eingehen, wie man innerhalb eines Eventhandler auf Steuerelemente des Templates zugreifen kann. Als Beispiel nehme ich hier einen LinkButton..
protected virtual void btnLogIn_Click(object sender, EventArgs e) {
txtBox = (TextBox) ((Control)sender).FindControl ( "txtUserName" ); if (txtBox != null) { userName = txtBox.Text ; }
}
Der Zugriff erfolgt genau wie bei der InitializeSkin Methode über FindControl. Hier muss man nun lediglich den Parameter sender nehmen und die Methode FindControl darauf anwenden.
Ich habe gerade eine Komponente von mir nach C# portiert - voher VB.Net. Übrigens geht das sehr gut mit SharpDevelopment.
Nun ja auf jeden Fall habe ich in VB.Net eine Berechnung gemacht
iPageCount = Convert.ToInt32(System.Math.Ceiling(RecordCount / PagingCount))
Nach C# konveritert sieht das nun so aus:
iPageCount = Convert.ToInt32(System.Math.Ceiling( RecordCount / PagingCount ));
Jetzt muss ich dazusagen, dass die beiden Werte RecordCount und PagingCount von Typ Integer sind. Wenn man nun in C# die Rechnung 6/4 = 1,5 durchführt kommt aber immer 1 raus. Das liegt daran das C# eine typsichere Sprache ist. Wenn man nun ein korrektes Ergebnis haben möchte muss man die beiden Werte zuerst in einen Double Typ umwandeln.
iPageCount = Convert.ToInt32(System.Math.Ceiling( Convert.ToDouble(RecordCount) / Convert.ToDouble(PagingCount) ));
Jetzt kommt bei der Rechnung (RecordCount / PagingCount) auch der gewünschte Wert von 1,5 raus. Durch die Funktion System.Math.Ceiling() wird hier auf den Wert 2 aufgerundet. (Ergänzung -> siehe Kommentar)
Durch eine Hashtable kann man nicht direkt via foreach Statement itterieren.
foreach(ProfileProperty currEntry in objInfo.ExtentedProperty) { string sUsername = currEntry.Username; }
Wenn man so einen Konstrukt abbilden muss dann geht das durch folgenden Umweg:
ProfileProperty baseProp = null ;
foreach(System.Collections.DictionaryEntry currEntry in objInfo.ExtentedProperty) { baseProp = (ProfileProperty)currEntry.Value ; }
Wichtig ist hierbei das man bei der Typumwandlung currEntry.Value zur Konvertierung nimmt, denn sonst gibt es eine Exception.
Wer schon mal versucht hat bei einem DataRepeater Radiobuttons hinzuzufügen wird bestimmt ähnliche graue Haare bekommen haben wie ich heute. Die Radiobuttons werden zwar sehr schön angezeigt aber leider funktioniert das Gruppieren von diesen Elementen überhaupt nicht. Das liegt daran das die Klasse Radiobuttons das Interface "INamingContainer" implementiert und somit jeder RadioButton einen eigenen Namen bekommt. Auch das Attribut "GroupName" bleibt ohne Wirkung...
Abhilfe schafft da da ein eigenes ASP.NET Control das unter der URL
http://www.codeproject.com/aspnet/How_group_RButtons.asp
zu finden ist.
Eine Erweiterung für einen Postback gibt es dann noch hier:
http://www.codeproject.com/aspnet/groupradiobuttons.asp
Allerdings funktioniert dieser Postback nicht wirklich und deswegen habe ich einen kleine Trick angewendet .. (achtung! Jetzt wird es kompliziert *lach*):
<GaliNeo:GroupRadioButton AutoPostBack=True OnCheckedChanged="rbtnProduct_CheckedChanged" id="rbtnProduct" runat="server" GroupName="SelectProd" />
public void rbtnProduct_CheckedChanged(object sender, System.EventArgs e) { string sCommandArgument = ((GroupRadioButton)sender).CommandArgument ; Response.Redirect ("http://localhost/dotnetnuke/DesktopModules/GaliNeo/OnlineStore/DashboardAddToCart.aspx?ProductId=" + sCommandArgument, true) ;
}
Mit dieser Lösung funktioniert das nun einwandfrei .....
Hier ein kurzer Beispielcode, wie man schnell eine Randomzeichenfolge erstellen kann. Nützlich z.B. für Passwörter oder ähnliches.
Ausbauen kann man diesen Bereich jetzt natürlich noch indem man Buchstaben wahlweise groß oder klein schreibt.
string alphabets = "abcdefghijklmnopqrstuvwxyz"; string numbers = "01234567890123456789012345"; StringBuilder randomstring = new StringBuilder(); Random r = new Random(); for(int j=0; j<=20;j++) { for(int i=0;i<=5;i++) { randomstring.Append(alphabets[r.Next(alphabets.Length)]); randomstring.Append(numbers[r.Next(numbers.Length)]); }
}
Nachdem ich ein paar sehr witzige Stunden mit den Installationsroutinen (für Module) von DotNetNuke hatte und schon fast verzweifelt habe, kam eine gute Fee und holte mich da raus ... aber alles hübsch der Reihe nach!
Ich habe ein eigenes Module geschrieben und dieses DNN Module hatte eine wahnsinnige Enterprise Funktionlität - nämlich folgende:
SET newOrderno = ((SELECT MAX(OderNo) FROM TABLE) + 1)
Dieses funktionierte auch einwandfrei, allerdings als ich dann das Modul zusammen packte und es auf einem Server installieren wollte, spuckte die Installation immer einen SQL Fehler aus ... "Fehler in der Nähe von 1" Ist auch logisch, denn was da ankam sah so aus:
SET newOrderno = ((SELECT MAX(OderNo) FROM TABLE) 1)
Das "+" fehlte also ... um das jetzt hier mal abzukürzen: Es lag an dem Dateiformat .. die Textdatei mit den SQL-Befehlen war als ANSI Datei abgespeichert. Nachdem ich diese Datei im UTF-8 Format abgespeicher hatte war das Problem behoben und das "+" stand im SQL-Befehl...
Zum Glück gibt es das www.dnnportal.de und Hans-Peter, der auch Nachts noch gute Tipps hat :)
Nur mal so nebenbei: Wenn man eine Textdatei z.B. als Templatevorlage ausließt und es fehlen die Umlaute .. ja dann würde ich diese auch mal im UTF-8 Format speichern....dann beim Auslesen der Datei noch das richtige Format angeben und schon ist mal alle Sorgen los!
Ich hatte das Problem, dass ASP.NET eine Textbox im Modus "MultiLine" nicht richtige Breite und Höhe für den Firefox rendert.
Im HTML Code sah das so aus:
IE: <textarea name="txtComment" id="txtComment" style="height:226px;width:100%;">
Firefox: <textarea name="txtComment" id="txtComment">
Die Lösung des Problem ist es, die Eigenschaften Rows und Cols zu setzen - dann funktioniert es auch im Firefox.
Oder der saubere Weg (aufgenommen wegen des Kommentars), die browserCaps modifizieren:
<browserCaps> <!-- GECKO Based Browsers (Netscape 6+, Mozilla/Firefox, ...) //--> <case match="^Mozilla\/5\.0.+rv:(\d\.\d\.\d).+Gecko"> browser=Gecko type=${type} frames=true tables=true cookies=true javascript=true javaapplets=true ecmascriptversion=1.5 w3cdomversion=1.0 css1=true css2=true xml=true tagwriter=System.Web.UI.HtmlTextWriter <case match="rv:(?'version'(?'major'\d+)(?'minor'\.\d+)(?'letters'\w*))"> version=${version} majorversion=${major} minorversion=${minor} <case match="^b" with="${letters}"> beta=true </case> </case> </case>
</browserCaps>
Weiter Infos gibt es unter http://slingfive.com/pages/code/browserCaps/
Hier in kurzes Codebeispiel, wie man aus einer HTML Farbe eine DotNet-Farbe machen kann.
Die Umwandlung ist denkbar einfach, denn das .NET Framework hat dafür bereits eine Funktion:
System.Drawing.ColorTranslator.FromHtml(#000000 )
Das wäre auch schon das ganze Geheimnis!
Für alle die keine Lizenz von CodeSmith kaufen möchten, aber auf den Luxus der Codegeneriung nicht verzichten möchten, gibt es eine Alternative.
Diese Alternative nennt sich MyGeneration und ist zu finden unter: http://www.mygenerationsoftware.com
Dieses Tool ist lizenzkostenfrei und biedet alles was man benötigt. Zumindest ist es in meinem Bereich noch nicht an seine Grenzen gekommen. Was mir lediglich fehlt ist eine Art Batch-Job, da es schon manchmal lästig ist die einzelne Gerneriung von Hand anzustoßen.
Es gibt auch schon für jede Menge Zwecke / Anwendungsfälle Templates - natürlich auch für DotNetNuke (!). Das Erstellen von MyGeneration-Templates finde ich etwas besser und intuitiver gelößt - kann aber auch nur Einbildung sein 
Das Tool Reflector for .NET habe ich bereits vor ein paar Monaten als ein cooles Tool hier im Blog erwähnt. Jetzt habe ich vor kurzen ein noch geileres Plug-In dafür entdeckt:
Reflector.FileDisassembler
Das Tool ist von Denis Bauer und erzeugt Source-Code Dateien aus einer .NET Assembly. Es wird einfach in den Reflector for .NET eingebunden und schon kann man sich nicht nur Methoden anschauen sondern sich direkt ganze Files erzeugen lassen :)
Ein wirklich cooles Tool für .NET ....
Das Schreiben in das Eventlog von Windows ist mit Sicherheit kein Geheimnis mehr und es gibt sehr viele Beispiele dafür. Hier zeige ich nur schnell, wie man in ein eigens - also nicht system, security, usw. - Eventlog von .NET (DotNet) ansprechen kann.
Wie eigentlich fasst alles bei mir ist das in C# geschrieben...
EventLog eLog = null; // Holds the event log reference. EventLogEntry eLogEntry = null; // A single entry.
// To create a special log, then you need to // register an event source first (as you already did in // your example code). if ( ! EventLog.SourceExists( "GaliNeo_Job_Source" ) ) {
// Create the new event source. EventLog.CreateEventSource( "GaliNeo_Job_Source", "GaliNeo_Job_Log", "." );
}
// Register the new event source. eLog = new EventLog( "GaliNeo_Job_Log" ); eLog.Source = "GaliNeo_Job_Source";
eLog.WriteEntry("My Message,EventLogEntryType.Information) ;
// or EventLog.WriteEntry( "GaliNeo_Job_Source", "Special Message", EventLogEntryType.Information, 12, 22 );
Mit den paar Zeilen C# ist das erledigt und man kann eigene EventLog schreiben und später die Daten etwas besser trennen.
Super klasse (!) ich habe heute den gesamten Nachmittag verschwendet und habe mal wieder an mir und meinen Verstand gezweifelt!
Ich arbeite gerade an einem TabPage - Control. Als Vorlage habe ich den Wizard von DotNetNuke genommen und den Rest reinprogrammiert. Alles gar kein Problem - nur etwas Arbeit.
Dann hatte ich aber das Problem, dass z.B. die ASP:Textbox ihren Viewstate verlor. Nach langen suchen und google, ohne jeden Erfolg, habe ich dann alles auskommentiert und dann Stückchen für Stückchen wieder reingenommen.
Was soll ich sagen, diese Zeile:
_tabCtrl.Rows.Insert(0,_parentTr) ;
ist dafür verantwortlich.
Ich habe ein Tabelle und füge dynamisch eine Zeile an erste Stelle ein... dadurch scheint dann der ViewState aller Elemente, die darunter angeordnet sind weg zu sein.
Jetzt setze ich halt einfach eine zweite Tabelle drüber und dann läuft es.
Seit zwei Jahren veranstalltet Microsoft Webcast. Das sind technische Vorträge / Präsentationen die man sich über das Internet anschauen kann.
Nun gibt es eine DVD mit allen bisherigen Webcast. Diese kann man bei Microsoft kostenlos bestellen:
hier bestellen..
Hier eine kleine Übersicht, wie man in .NET runden kann ..
Abrunden:
Wenn man immer abrunde möchte muss man die Funktion Math.Floor verwenden. Floor bekommt als Parameter einen Double-Typ und gibt den nächst kleinere Ganzzahl zurück.
Hier ein Beispiel:
System.Console.WriteLine("Floor " + System.Math.Floor(1.1)); System.Console.WriteLine("Floor " + System.Math.Floor(1.5)); System.Console.WriteLine("Floor " + System.Math.Floor(1.9));
Liefert als Ergebnis folgends Zurück:
Floor: 1 Floor: 1 Floor: 1
Aufrunden:
Im Gegensatz dazu liefert die Funktion System.Math.Ceiling immer die nächst höhere Ganzzahl
Beispiel:
System.Console.WriteLine("Ceiling " + System.Math.Ceiling(1.1)); System.Console.WriteLine("Ceiling " + System.Math.Ceiling(1.5)); System.Console.WriteLine("Ceiling " + System.Math.Ceiling(1.9));
Liefert folgendes zurück:
Ceiling 2 Ceiling 2 Ceiling 2
"Normals Runden"
Die Funktion System.Math.Round rundet dagegen in Abhängigkeit der letzten Zahl auf oder ab.
System.Console.WriteLine("Round " + System.Math.Round(1.1)); System.Console.WriteLine("Round " + System.Math.Round(1.5)); System.Console.WriteLine("Round " + System.Math.Round(1.9));
Liefert als Ergebnis:
Round 1 Round 2 Round 2
Wir suchen zur Entwicklung von Skins für DotNetNuke einen Webdesigner mit guten HTML / CSS-Kenntnissen auf freiberuflicher Basis. Schwerpunkt liegt auf der grafischen Gestaltung.
Bei Interesse bitte Kontakt per eMail aufnehmen mit Michael Gandke (kontakt2005 @ gandke.de). Bitte zwei oder drei bisherige Projekte / Websites (inkl. URL) mit angeben.
Mal in eigener Sache: Wir suchen zur Entwicklung von Webanwendungen unter Microsoft .NET einen Kollegen mit guten ASP.NET-Kenntnissen zur Festanstellung (Großraum Mönchengladbach). Die Zusammenarbeit kann auch freiberuflich auf Projektbasis erfolgen. SQL-Kenntnisse sollten ebenfalls vorhanden sein sowie Erfahrungen mit eCommerce / Online-Shops.
Entwickelt werden hauptsächlich Module für DotNetNuke unter C# und/oder VB.NET. Bei Interesse bitte Kontakt per eMail aufnehmen mit Michael Gandke (kontakt2005 @ gandke.de). Eine kurze Beschreibung der bisherigen Projekte reicht aus.
Wer bei der Erstellung von ASPX / ASCX eine Basisklasse verwendet, kann dabei Probleme bekommen.
Ich hatte bis her immer folgende Fehlermeldung in der VS.NET IDE beim designen von den ASPX / ASXC Seiten.
<Fehlermeldung> Die Datei konnte nicht im Web-Form-Desinger geladen werden. Korrigieren Sie den folgenden Fehler, und laden Sie sie dann erneut:
....
Stellen Sie sicher, dass alle auf der Seite verwendeten Klassen im Projekt erstellt oder referenziert wurde. </Fehlermeldung>
Nachdem ich die .Net-Sicherheitsrechtlinie von der Intranet-Zone auf Full-Trust gestellen habe, konnte VS.NET die ASPX / ASCX auch wieder darstellen.
Microsoft hat eine Liste mit "Breaking Changes" zwischen dem .NET Framework 1.1 und 2.0 Beta 2 sowie den Änderungen von .NET 2.0 Beta 1 zu Beta 2 veröffentlicht.
Diese Liste steht im Compiled-Help-Format zu Verfügung und enthält außerdem alle Änderungen bei ASP.NET, ADO.NET und Windows Forms.
Wie bekommt man aus einem String - Array einen kommaseoarierten String? Wer es braucht bitte:
Dim commaSeparatedValues As String = _ String.Join(",", myArrayList.ToArray(String.Empty.GetType()))
Dazu gibt es es dann auch noch eine Link aus der MSDN.
DotNetRocks ist eine Radiosendung die sich mit allem rund um das Thema .NET befasst. In einer der letzten Sendungen war ein paar der Köpfe von DotNetNuke als Gäste eingeladen. Dabei handelte es sich um "Jim Duffy" und "Shaun Walker"!
Wer sich diese Sendung anhören möchte ... hier ist der direkte Link:
http://www.dotnetrocks.com/default.aspx?showID=113
Echt cool
Die Inhalte sind:
- Wichtige Änderungen zwischen der Version 2 und der aktuellen Version 3
- Der Gedanke von Open Source
- Die Zukunft von DotNetNuke
Wer schon immer mal wissen wollte, wie man .NET (hier am Beispiel von C#), die aktuelle Kalenderwoche ermitellt .. bitteschön hier ein Beispiel:
using System; using System.Globalization ;
namespace ConsoleApplication1 { class Class1 { [STAThread] static void Main(string[] args) { DateTime dt = DateTime.Now; System.Globalization.Calendar objCal = CultureInfo.CurrentCulture.Calendar; int weekofyear = objCal.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); Console.WriteLine(weekofyear.ToString() ) ; } } }
Mit dem Objekt objCal ist man z.B. auch in der Lage Schaltjahre zu ermitteln...
Das war jetzt mal wieder keine wirklicher Quantensprung aber auf Anhieb habe ich es nicht im Netz gefunden. Gehört auf jeden Fall zu Kategorie "Nützlicher Code".
Eine sehr coole Möglichkeit für .NET Entwickler sich mit dem Open Source Projekt Mono zu beschäftigen - ohne dabei direkt ein System mit Linux zu installieren - bietet eine Lösung Namens Monopix. Dabei handelt es sich um erweiterte Lösung von Knoppix die folgende Komponten beinhaltet:
Sehr cool sind auch das Tutorails, dabei handelt es sich um Videos:
http://www.monoppix.com/tutorials.php
Auf der Suche nach Möglichkeiten div. Kurven darzustellen bin ich über eine sehr gute Chart Komponente gestolpert, die auch noch aus 100% .NET Code besteht. Entwickelt wurde die Komponente / Control komplett in C#...
Diese findet man unter:
http://zedgraph.sourceforge.net/
Die Einarbeitung ging erstaunlich schnell und nachdem ich dann auch noch einen Aritkel über genau diese Chart Komponente gefunden habe, ging es fast von alleine. Ich kann also nur folgenden Beitrag jedem ans Herz legen der sich mit ZedGraph auseinander setzen möchte.
http://www.codeproject.com/csharp/ZedGraph.asp
Hier ist ein cooler Artikel der kurz und knapp eine Anleitung zum Erstellen eines Windows Service unter DotNet gibt:
http://www.developer.com/net/csharp/article.php/10918_2173801_1
Habe ihn gerade entdeckt, da ich auf der Suche war den Scheduler Service von DotNetNuke zu umgehen. Der hat nämlich so einige negative Eigenschaften, die ich für meinen Anwendungsfall nicht gebrauchen kann.
So ist der Scheduler von DotNetNuke nur verfügbar, wenn auch die Webanwendung aktiv ist. Sollte es also vorkommen, das niemand im Portal online ist und die Webanwendung ist heruntergefahren ... blöde Sache!
Nun ja, deswegen versuche ich das jetzt mit Hilfe eines (DotNet) Windows Service zu implementieren.
Bei einem Portal mit DotNetNuke besteht das Problem, dass ne ganze Menge E-Mailtraffic entsteht. Es gibt eine ganze Menge an Funktionen und Modulen, die E-Mail-Benachrichtigungen durch die Gegend schicken. Besonders beim Thema Newsletter versagt DotNetNuke ein wenig - immerhin sprechen wir von mittlerweile ca. 20.000 Usern (oder E-Mailadressen).
Da ich schon seit langem die MSMQ etwas stärker involvieren wollte, war hier die beste Möglichkeit dieses endlich zu realisieren. Eine E-Mail ist ja so wieso ein asynchroner Prozess und was hindert einen also daran die E-Mails in eine gemeinsame "Message Queuing Services" zu schieben, um diese von einer Stelle aus zu verschicken.
MSMQ steht für "Microsoft Message Queuing Services" und ist ein wenig, um asynchrone Prozesse oder man kann diese auch Workflows nennen, abzubilden.
Ein Windows Service sorgt für das Prozessmodell, denn irgendwie muss das Programm zum Abrufen der MSMQ und zum Versenden der E-Mails ja "leben". Die Erstellung eines Windows Service ist nicht spektakulär, deswegen erspare ich mir Details. Wie man einen Versand von E-Mail realisiert ist nun auch ein alter Hut .. damit will ich nun wirklich keinen langweilen.
Okay, ich gebe zu das ist nicht so die super Erfindung aber eine ganz nette Sache um Anwendung DotNetNuke etwas zu entlasten - das "Reinschieben" einer Nachricht in die MSMQ geht nun mal schneller als das direkte Versenden.
Vorteile sind z.B. auch, dass man Transaktionen nutzen kann um so sicherzustellen, dass die E-Mail an den SMTP-Server auch sicher übergeben wurde.
Teilweise werden die Nachrichten direkt von DotNetNuke in die MSMQ geschoben oder aber wenn noch viel "Vorarbeit" geleistet werden muss kommen hier der DotNetNuke Scheduler Mechanismus zum Einsatz.
Warum ich diesen nicht benutze um die E-Mails aus DotNetNuke zu versenden? .. ganz einfach: Ich wollte eine allgemein gültige Schnittstelle haben!
Wer einen seltsamen JavaScript-Fehler bei DotNetNuke bekommt und einfach keine Lösung findet - vielleicht ist da ja eine:
Also der Fehler ist folgender: Beim Laden einer Seite kommt die eine JavaScript-Meldung..
Zeile: 2 Zeichen: 1 Fehler: Syntaxfehler Code: 0
Habe mir einen Wolf danach gesucht. Habe dann den HTTP-Header mitgeschrieben und gesehen das zwischendurch auf die 404 Seite weitergeleitet wurde.
Die Datei: aspnet_client/system_web/1_1_4322/WebUIValidation.js sollte geladen werde, konnte aber nicht gefunden wurden.
Da klingelte es - es fehlten das benötigte aspnet_client - Verzeichnis im Stammverzeich der DotNetNuke Installation.
Ich denkde das dieser Fehler nicht nur für DotNetNuke Anwendungen sonder auch für jede andere ASP.NET Anwendung zutrifft....
Bei längeren Speichervorgängen hat man des öfteren das Problem, dass ein User dazu verleitet wird erneut auf "Speichern" zu klicken. Gerade bei Webanwendungen (ASP.NET) ist das nicht schön.
Um dieses zu unterbinden muss man ein wenig JavaScript-Code in die ASP.NET Seite einbinden. Der folgende JavaScript-Code zeigt, wie man dieses Problem lösen kann. Dabei werden sogar evtl. mögliche Client-Side-Validierungen berücksichtigt.
Dim sbValid As New System.Text.StringBuilder
sbValid.Append("if (typeof(Page_ClientValidate) == 'function') { ") sbValid.Append("if (Page_ClientValidate() == false) { return false; }} ") sbValid.Append("this.value = 'Bitte warten...';") sbValid.Append("this.disabled = true;") 'GetPostBackEventReference obtains a reference to a client-side script function that causes the server to post back to the page. sbValid.Append(Me.Page.GetPostBackEventReference(Me.cmdUpdate)) sbValid.Append(";")
cmdUpdate.Attributes.Add("onclick", sbValid.ToString())
Das Beispiel habe ich jetzt in VB.NET umgesetzt - in C# geht das natürlich genau so. Die Übersetzung erspare ich mir jetzt, da es so tival ist 
Diesen Code positioniert in der "InitializeComponent()" Methode einer ASP.NET Seite.
Wie kann man an eine Strored Procedure eine List übergeben, die für einen WHERE Part benötigt werden.
WHERE PLZ IN '22222','22222'
Zunächst unterstützen Stored Procedure keine Array's, deswegen muss man ein wenig tricksen.
Create Procedure Gibmaluser
@sParamList nvarchar(400)
AS
DECLARE @sqlStr nvarchar(4000)
@sqlStr = 'SELECT * FROM Meiner_Tabelle WHERE Name In (' + @sParamList + ')' EXEC @sqlStr
go
Um diese SP nun aufzurufen muss man dann lediglich folgendes machen:
sp_GetVendorsByList '''1'',''2'',''3'''
Die ganze Geschichte brauche ich, wie sollte es auch anders sein, für DotNetNuke und der Suche nach Benutzernprofilen.
PS: Das ist natürlich jetzt kein Hexenwerk und man findet schon jede Menge Stuff darüber bei google, aber ich gebe doch so gerne auch meine Senf dazu 
Für verschiedene Szenarien ist es notwendig, dass Sie den Inhalt einer <form /> zu fremden URL posten müssen. Ein Beispiel für eine solche Anwendung wäre z.B. die Einbindung von Payment-Systemen. Die Problematik besteht darin, dass bei ASPX-Seiten kein anderes Ziel als sich selber erlauben bzw. einstellbar sind. Natürlich gibt es für solche Momente auch eine Lösung - ja sogar mehrere:
Eine Lösung wäre folgende Methode:
RemotePost myremotepost = new RemotePost() myremotepost.Url = "http://www.galineo.de/demo/HttpRequestDemoServer.aspx" myremotepost.Add("Name","Mustermann") myremotepost.Add("Vorname","Fritz") myremotepost.Post()
Die RemotePost - Klasse ist sehr gut für solche Zwecke geeignet.
Die Empfangsseite kann wie gewohnt die Inhalte auslesen:
<%@ Page Language="C#" %>
<script runat="server">
void Page_Load(object sender, EventArgs e){ if (Request.Form["Name" != null ){ Response.Write("Name : " + Request.Form["Name" + "")}
if(Request.Form["Vorname" != null ){ Response.Write("Vorname: " +Request.Form["Vorname" + "")} } </script>
Für die DotNetNuke Plattform gibt es nur eine limitierte Anzahl von ECommererce-Lösungen.
Folgende sind derzeit erhältlich:
Nun wird eine weitere Lösung hinzukommen. Da mich keine der Lösungen total überzeugt hat (obwohl CataLook schon fast ein Knaller ist) werde ich nun eine eigenen Implementieren. Eine Schwachstelle soll von Beginn an nicht auftretten: schlechte Usability.
Es wird mit Sicherheit noch einige Zeit dauern bis die Lösung fertig ist aber wer noch Zeit zu warten hat .. soll warten :)
Ach, es wird ein 100% DNN Modul(e) und komplett in C# entwickelt. Will hier keine Glaubenskrieg oder wilde Diskussionen lostretten, aber ich mag C# lieber ... auch wenn es nur wenige Punkte Vorsprung hat zu VB.Net 
Das Oracle Technology Network hat eine neue Webseite mit dem Namen ".NET Developer Center" online gestellt. Hier gibt es alle wichtigen Informationen für die Entwicklung von .NET-Anwendungen, die Oracle-Datenbanken nutzen.
Um optimal mit einer Oracle-Datenbank zusammen zuarbeiten gibt es ein Visual Studio Plug-In zum freien Download.
http://www.oracle.com/technology/tech/dotnet/
Das DotNetNuke - Team hat einen neue Betaversion (BETA 3.0.11) lanciert. Diese findet man wie immer unter http://www.dotnetnuke.com. Die Installation verläuft wie immer ohne Probleme, selbst ein Update von der 3.0.10 war möglich.
Dieses ist laut Ankündigung die letzte Beta (!) die nächst Version soll eine die 3.0 Final sein.
Wer nach einer Kompilierung von einen DotNet - Projekt folgende Fehlermeldung erhält:
"Warnung: Die Abhängigkeit 'MeinNamespace, Version=1.0.1446.25628, Culture=neutral' in Projekt 'NocheinNamespace' kann nicht in das Ausführungsverzeichnis kopiert werden, da sie den Verweis ''MeinNamespace, Version=1.0.1446.32003, Culture=neutral' überschreiben würde."
sollte sich einfach Property "Lokale Kopie" anschauen und diese so einstellen, dass die Fehlermeldung wieder verschwindet!
In Dotnet-Kreisen ist es ja längst bekannt, ein OpenSource - Projekt mit dem Namen Mono, beschäftigt sich damit DotNet auf Linux zu portieren. Sehr spannender Stuff :)Das dieses auch in der Praxis funktionieren kann, wurde durch ein paar ASP.NET Anwendungen bewiesen:
Unter http://go-mono.com/ports/ findet man einige Webanwendungen die auf Linux (also unter dem Mono Framework) laufen.
Microsoft bietet in den nächsten Tagen mal wieder eine Reihe von Webcast zum Thema MS SQL Server 2005.
Themen dabei sind:
- Was gibt es neues für den Entwickler
- T-SQL-Erweiterungen im SQL Server 2005
- XML in SQL Server 2005
- Stored Procedures, Funktionen und Aggregationen mit .NET
- User Defined Types
- ADO.NET 2.0 und SQL Server 2005
- Integration Services
- Einführung in den SQL Server Service Broker
- Das neue Sicherheitsmodell
- Analysis Services für Entwickler
- Volltextsuche in SQL Server 2005
- Replikation mit SQL Server 2005
Termine und weiter Infos findet man unter: https://www.microsoft.com/germany/msdn/webcasts/kuenftige.aspx
Nachdem ich mich heute den ganzen Abend über mein Notebook geärgert habe und ich es nun neu Aufsetzen muss, brauchte ich auf jeden Fall noch ein Erfolgserlebnis, bevor ich schlafen gehe!
In den letzten Tagen ist ein Projekt ins Leben gerufen wurden, dass sich mit DotNetNuke und der OpenSource Datenbank Firebird beschäftigt. Es gibt für DNN 3 leider keine weitern Datenbankprovider. So haben wir beschlossen, eine Unterstützung von Firebird für DNN 3 zu implementieren. Später wollen wir dann auch MySQL mit ins Boot nehmen - Firebird ist quasi zum warm werden.
Also; weil mein Notebook so schön arbeitet und nur von Zeit zu Zeit eine CD verlangt, habe ich angefangen meine anderen Rechner mit Firebird auszustatten. Die Installation und Einrichtung verlief ohne Probleme :) und ein paar Minuten später konnte ich auch schon die ersten Daten auslesen. Na das sieht alles ganz gut aus .... mal schauen wie es weitergeht.
Alles weiter werde ich hier berichten. Leider ist meine Zeit im Augenblick sehr knapp, da ich gerade versuche mit Hilfe von DotNetNuke die www.lowfett.de neu aufzubauen.
Naja, jetzt kann ich später die Augen getrost zu machen gehen. :)
I'm rocking the world, yeah 
|