DotNetNuke export Users with Passwords

Bei einem Ur-Alt Portal (DotNetNuke 3.2.2) das noch hobbymäßig betreut habe, steht nun der Wechsel z [Mehr]

Seitentitel im Breadcrumb Skinobject

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="&nbsp;>&nbsp;" UseTitle="True" />

C# URL Shorter for TinyUrl or bit.ly

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.

RibbonBar Control Panel jetzt auch in der Community Edition

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 TasksCurrent PageAdminHostDer 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.

DotNetNuke Context Menu Hiding / Firefox 3.6

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 = 1Die Wert von 1 einfach erhöhren z.B. 10000 und anschliesend wird das Kontext-Menü von den DotNetNuke Modulen auch wieder im Firefox angezeigt.

Social Networks Publishing-Dienst (Part 2)

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.

HTML Form Data with c# as GET

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.

Social Networks Publishing-Dienst

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 :)

DotNetNuke Standardcontrol portal:url und die Auswahl "keine Auswahl"

Das DNN Control portal:url ist ja sehr flexibel und damit kann man vieles abfangen. Auwahl von Seiten, Verlinkungen, Benutzern, internes Dateisystem, etc. Wenn das Feld aber kein Pflichtfeld ist der Benutzer auch nachträglich noch die Möglichkeit haben soll den Werte wieder zu entfernen, dann muss bei dem Control eine Property setzen:required="False"Durch diesen Parameter erscheint dann "keine Auswahl" in der Drowdownbox.

Webservice Kommunikation zwischen .NET ASMX und PHP

Ich hatte das "Vergnügen" für die Integration eines Portals mit einem anderen die Schnittstellen zu definieren. Unsere Plattform ist natürlich eine ASP.NET Anwendung (DotNetNuke) und auf der Gegenseite wurde eine Umgebung mit PHP aufgebaut. Wir einigten uns auf einen Webservices ... mal davon abgesehen, dass mein Gegenüber sich noch nie ernsthafter mit den Webservice-Spezifikationen auseinandergesetzt hat ... ist das rein von der Interoperabilität doch bestens geeignet. In der Praxis war es dann aber nicht ganz so einfach, die Daten auch wirklich vom PHP-Code an den ASMX Dienst zu übertragen. Die Methode wurde zwar immer aufgerufen, leider kamen aber keinerlei Parameter an. Schweren herzens habe ich sogar den Kompromiss gemacht und hab in die Definition der Webservice-Methode einzelne Parameter aufgelistet - anstelle einer nachrichtenbasierten Kommunikation mit einem einzigen Parameter. Vereinfacht dargestellt sah die Methode bzw. die Definition der Schnittstelle so aus: [Webmethod]public string Gibmirdaten(string name, stirng vorname){ . . . . return "Ergebnis: " + name + ", " + vorname;}<pre><span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px">[Webmethod] <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">string</span> Gibmirdaten(<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">string</span> name, strrng vorname) { . . . . <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">return</span> <span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"Ergebnis: "</span> <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">+</span> name <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">+</span> <span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">", "</span> <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">+</span> vorname; }</span></pre<br><br><br>s<br>w<br>w<br>w<br>w<br>w<br>s<br><br><br>Man sollte meine, dass es in PHP genau so einfach ist, einen Webservice zu konsumieren, wie es in .NET ist (und dabei meine ich nicht so einen Schwachsinn wie Rechtsklick und Webverweis hinzufügen :)).Dank Google und einiger sehr hilfreicher Tutorials im Internet habe ich PHP-Krüppel es hinbekommen. Wichtig für die richtige Übertragung der Parameter ist die Umformung bzw. die Verpackung in ein Array. Die Methode new SoapParam(..) - wie man Sie des öfteren sieht - funktioniert leider nicht. Zumindest habe ich das in meine konkreten Beispiel und dem Zusammenspeil mit .NET festgestellt. Ein funktionierende SOAP-Client-Proxy (eigentlich tut es weh so etwas dazu zu sagen) sieht wie folgt aus:var $SOAP = new SoapClient('http://www.meinesite.de/ParterUserReg.asmx?WSDL'); var $params = array('name' => 'Müller', 'vorname' => 'Daniel'); $SOAP->Gibmirdaten($params ); Damit kann man die einzlenen Werte übermitteln.Wenn jemand einen anderen und vielleicht sogar besseren Weg kennt, dann bitte melden :)

iPhone-Anwedungen entwickelt in C# und .NET

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

Organisation von Projektreferenzen innerhalb eines Solution

Mir fällt sehr oft auf, dass beim Aufbau einer Anwendung mit mehreren Projekten innerhalb einer Solution, immer wieder eine direkte Abhängigkeit geschaffen wird, indem man beim Projekt sagt: "Verweis hinzufügen" -> Projekte -> Das zu referenzierende Projekt.Gemacht wird so etwas z.B. wenn man die Datenobjekte / -definitionen getrennt von der Logik, Datenzugriff, etc. in einem eigenen Projekt verwalten möchte (was eigentlich so wieso immer getan werden sollte). Solange man alleine an einem Projekt arbeitet mag das noch okay sein und funktionieren; arbeitet man aber in größeren Projektteams zusammen, wo nicht immer alle die komplette Solution inkl. SourceCode Kompilieren sollen / möchten / können, muss man regelmäßig die Referenzen manuell neu aufbauen. Ich empfehle immer nur die kompilierte Assembly zu referenzieren und alle 1024x768 Normal 0 21 false false false DE X-NONE X-NONE MicrosoftInternetExplorer4 /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Normale Tabelle"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin;} genutzten Assemblies in einem gemeinsamen Ordner abzulegen. Dann ist es nämlich vollkommen egal, ob man die gesamte Solution, einen Teil oder sogar nur ein Projekt öffnet. Mehr Aufwand bedeutet das für die Konfiguration und Entwicklung auch nicht, da nur einmal bei der Anlage des Projektes ein Post-Build-Kommando in den Einstellungen des Projektes hinterlegt werden muss. Hier ein Beispiel dafür:xcopy /y /d "$(TargetPath)" "$(SolutionDir)SharedAssemblies\"Der Parameter "/d" sorgt dafür das nur aktueller Versionen kopiert werden und "/y" unterdrückt die Nachfrage, ob vorhandene Dateien überschrieben werden sollen und macht dieses einfach automatisch.By the way... eine schöne Übersicht der XCOPY Parameter gibt es hier bei MicrosoftDamit nun die Reihenfolge der Kompilierung richtig ist und auch Veränderungen von z.B. Basisklassen zuerst neu erzeugt werden, muss man unter den Projektabhängigkeiten nun die einzelnen Projekte angeben. Das ist kein Verweis (!) veranlasst aber Visual Studio in der richtigen Reihenfolge die Projekte zu erstellen!that's it

Das neue Silverlight ist da

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

Convert VS2003 Class Library to VS2008 Web Application Project

Bei der Weiterentwicklung eines recht alten Portals stand ich nun vor der Aufgabe eine aktuelle Entwicklungsumgebung aufzusetzen. Die bisherige Umgebung war DNN 3.2.2 und nun wurde das Portal auf die aktuelle Version von DNN (4.x) aktualisiert. Da ich auch nicht mehr mit Visual Studio 2003 entwickeln wollte, habe ich den SourceCode das Modul mit dem Conversion Wizard auf die aktuelle VSS Version 2008 konvertiert. Das Projekt vom Type ClassLibrary konnte aber nicht vernüftigt debugged werden, daher habe ich beschlossen das Projekt als WAP (Web Application Project) weiterzuentwickeln.Dafür muss man (nach erfolgreichem Durchlaufen des Conversion Wizard von VS2008) die Projektdatei mit einem Editor öffnen und anschließend die Zeile<ProjectType>Local</ProjectType>gegen <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>tauschen. Nach dem erneuten Öffnen der Projektmappe / des Projektes im Visual Studio wird diese nun als WAP angezeigt. Nun muss man nur noch die einzlnen ASCX / ASPX in eine Web-Anwendung konvertieren. Das ist auch sehr einfach zu erledigen: Die gewünschten Dateien Auswählen und im Kontextmenü den Punkt "In Webanwendung konvertieren" wählen. Nun werden im Hintergrund die *.designer.cs Dateien angelegt und gleichzeitig die Codebehind-Klassen als "partial" gekennzeichnet. Schon ist das Update von einer Class Library in ein Web Application Project fertig!Achso: Bitte die Konfiguration überprüfen und evtl. Anpassen...

IETester: Alle Internet Explore in einer Anwendung nutzen zur Kontrolle von Designanpassungen

Eine wirklich tolles neues Werkzeug ist die Software IETester, der die Entwicklung bzw. das Testen von neuen Webseiten deutlich vereinfacht. Man muss nicht alle IE dafür installiert haben und der Webentwickler benötigt nicht ständig 4 offene Browser / Anwendungen um die Seite zu sehen. Die einzelnen Browserversionen werden einfach in einem Tab geöffnet.Folgende IE-Versionen deckt der ITTester aktuell ab:IE 5.5IE 6IE 7IE 8 beta 1Aktuell befindet sich die Anwendung noch in einer sehr frühen Phase, dennoch macht der IETester einen vielversprechenden Eindruck und läuft recht stabil.

Debug-Konfiguration von WAP DNN Modulprojekten unter VS 2008 beim Fehler "virtuelles Verzeichnis"

Bei der Umstellung / Migration der Entwicklungsumgebung von Visual Studio 2003 (für ein Projekt wurden bisher Module für DNN 3.2.2 erstellt) auf Visual Studio 2008 und die Projektart WAP (Web Application Projects), bekam ich immer folgende Meldung bei der Konfiguration vom Server (IIS): Diese Konfiguration ist aber notwendig, damit man das WAP-DNN-Modul Projekt vernüftig debuggen kann. Die Meldung ist zunächst verwirrend, denn unter der angegebenen URL war bereits ein komplett lauffähiges DotNetNuke installiert und die URL war natürlich als Anwendung konfiguriert. Es konnte also nicht im IIS liegen (IIS unter Vista). Die Berechtigungen war auch richtig gesetzt und waren nicht der Grund für diese Meldung. Die Lösung war dann folgende Konfiguration: Bei Projekt-URL habe ich den kompletten Pfad zum Modul eingetragen (also z.B. http://gmsshop/desktopmodules/shopsystem) Damit nun die Verweise z.B. in den ASCX Dateien richtig funktionieren muss zwigend die Option "URL des Anwendungsstam überschreiben" aktiviert werden. Dann die eigentliche URL der DotNetNuke Installation in das dann verfügbare Textfeld schreiben Mit dieser Konfiguration startet Visual Studio 2008 das DotNetNuke Modul auch wieder im Debugmodus

Migration von benutzerdefinierter profile properties

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.

ASP.NET 2.0 Validatoren JavaScript Bug missing ; before statement

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.

Aktivierung der Human Friendly Urls bei DotNetNuke

Um in DotNetNuke für SEO besser geeignete URL's zu nutzen, muss man die web.config bearbeiten. Dieses läßt sich nur global und nich für jedes Portal einzeln aktivieren.<friendlyUrl defaultProvider="DNNFriendlyUrl">     <providers>         <clear />         <add name="DNNFriendlyUrl" type="DotNetNuke.Services.Url.FriendlyUrl.DNNFriendlyUrlProvider, DotNetNuke.HttpModules" includePageName="true" regexMatch="[^a-zA-Z0-9 _-]" urlformat="HumanFriendly"/>     </providers>  </friendlyUrl>Setzt man den Parameter urlformat auf "HumandFriendly", dann erhält man folgende URL:http://www.mydomain.com/DotNetnuke-installations-service.aspx Die unter DotNetNuke bezeichneten suchmaschinenfreundlichen URL's sehen wie folgt aus:http://www.mydomain.com/dotnetnuke/installation-service/tabId/566/default.aspx Eigentlich ist die Humanfriendly-Lösung auch deutlich besser für die Suchmaschine geeignet, die Namensgebung stammt wohl noch aus grauer Vorzeit - die Verwendung von HumanFriendly-Urls ist auf jeden Fall zu empfehlen. Jede Seite im DotNetNuke-Portal ist über die drei möglichen Adressierungen ansprechbar:http://www.mydomain.com/default.aspx?tabId=566http://www.mydomain.com/dotnetnuke/installation-service/tabId/566/default.aspxhttp://www.mydomain.com/DotNetnuke-installations-service.aspx Eine Abwärtskompatibilität ist somit gegeben, was rein technisch ist das sehr angenehm ist. Aus Sicht der Suchmaschinenoptimierung ist diese Möglichkeit aber gefährlich, da hier die Gefahr des "Duplicated Content" entsteht und identische Inhalt über mehrere URL's erreichbar sind. Es ist also darauf zu achten, dass man eine saubere Weiterleitung einrichtet!

SELFHTML besser durchsuchen

Eine wichtige Anlaufstelle für Webentwickler, Webdesigner und alle die sich mit HTML, CSS und JavaScriptrumschlagen müssen ist SELFHTML. Unter  http://visualselfhtml.org gibt es jetzt eine Webanwendung die eine sehr gute und gezielte Suche erlaubt. Ein Stichwortverzeichnis macht die Anwendung so richtig klasse. Diese Webanwendung basiert auf jQuery .... cool :)

Final von Internet Explorer 8.0

Ich bin mir gar nicht sicher, ob es ein Grund zur Freunde ist, dass Mircosoft den IE 8.0 mittlerweile als Final veröffentlicht hat. Eigentlich freue ich mich ja immer über neue Softwareversionen und probiere alles sofort aus. Aktuell bin ich aber noch kritisch, ob man als Webagentur jetzt nicht noch mehr Ärger als ohnehin schon bekommt. Microsoft hat bei der mehr als zwei Jahre andauernden Entwicklung vom IE 8.0 viel Arbeit für de Bereiche Geschwindigkeit und Kompatibilität investiert aber bei dem Acid3-Test nur  20 von 100 möglichen Punkten bekommen. Dahingegen ist die vollständige CSS-2.1-Unterstützung und der der Acid2-Test keine Problem.Was Webentwickler bei der Kompatibilitätsansicht beachten müssen hat Kay Giza hier zusammengefasstAlle Leute die keine Lust auf ein automatisches Update haben, sollten folgendes Toolkit von Mircosoft benutzen, um ein Update zu deaktiveren.

SQL 2005 Server error: Property IsLocked is not available for Login '[username]'

Heute musste ich feststellen das auf einem Windows 2003 Server mit einer Instance vom MS SQL Server 2005 Express DotNetNuke die Arbeit eingestellt hat. Ein Blick in das Eventlog vom Server ergab, das sich der Benutzer nicht mehr am SQL-Server anmelden konnte. Als ich die Eigenschaften des entsprechenden Datenbank-Benutzers überprüfen wollte, kam die Meldung: Property IsLocked is not available for Login '[username]'. This property may not exist for this object, or may not be retrievable due to insufficient access rights. (Microsoft.SqlServer.Smo) Ein Wechsel zwischen dem Anmeldemodus Windows-Auth und gemischter Modus betrachte keine Veränderung - diesen Tipp hatte ich in einem Forum gelesen. Was geholfen hat war das absetzen vom folgendem SQL-Befehl:ALTER LOGIN [usermae] WITH PASSWORD=N'meintollespwd',CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF, DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english]GOALTER LOGIN [username] ENABLE  Damit konnte sich DotNetNuke wieder anmelden und auch die Eigenschaften vom Benutzer waren wieder einsehbar und konnten über die Managmentkonsole vom SQL-Server modifiziert werden. Die wirkliche Ursache habe ich noch nicht gefunden - zumindest läuft die Webanwendung wieder!

Javascript f&Uuml;r Galleries, Slideshows and Lightboxes

Aktuell beschäftige ich mich mit der Entwicklung einer kleinen praktischen Komponente, die ein Web 2.0 Popup-Fenster für DotNetNuke Module bereitstellt. Dabei geht es weniger darum eine Bilder anzeigen zu lassen, das Hauptziel ist die Nutzung für Bearbeitungsfenster. Ebenfalls soll das Modul auch in unser Videomodul einfließen, damit das Videos in einem Popup angezeigt werden können. Dazu vielleicht aber später mehr....Auf eine google-Suche habe ich diese Seite gefunden, die 56 Skripts für Galliers, Slideshows auflistet und direkt zu den entsprechenden Websiten verlinkt. Mein Favorit ist eigentlich lightbox aber über den Tellerran zu schauen kann ja nie schaden. Nachtrag: Soeben habe ich einen Kommentar per E-Mail erhalten und mir wurde da http://highslide.com/ ans Herz gelegt, ist zwar nicht kostenfrei aber bietet schon eine ganze Menge an Funktionalität .... man hat doch wirklich die "Qual der Wahl"

but its type (System.Web.UI.UpdatePanel) is not compatible with the type of control

In unserem DotNetNuke Shop Modul wird im Administationsbereich einiges mit ASP.NET AJAX durchgeführt. Bisher verlief die Installation der Entwicklungsumgebung auch immer ohne Probleme. Bei einem Kollegen, kam es aber zu einer echt blöden Fehlermeldung: DotNetNuke.Services.Exceptions.ModuleLoadException: The base class includes the field 'pnlExtPrice', but its type (System.Web.UI.UpdatePanel) is not compatible with the type of control (System.Web.UI.UpdatePanel). ---> System.Web.HttpParseException: The base class includes the field 'pnlExtPrice', but its type (System.Web.UI.UpdatePanel) is not compatible with the type of control (System.Web.UI.UpdatePanel). ---> System.Web.HttpParseException: The base class includes the field 'pnlExtPrice', but its type (System.Web.UI.UpdatePanel) is not compatible with the type of control (System.Web.UI.UpdatePanel). at System.Web.Compilation.BaseTemplateCodeDomTreeGenerator.BuildFieldDeclaration(ControlBuilder builder) at System.Web.Compilation.BaseTemplateCodeDomTreeGenerator.BuildSourceDataTreeFromBuilder(ControlBuilder builder, Boolean fInTemplate, Boolean topLevelControlInTemplate, PropertyEntry pse) at System.Web.Compilation.BaseTemplateCodeDomTreeGenerator.BuildSourceDataTreeFromBuilder(ControlBuilder builder, Boolean fInTemplate, Boolean topLevelControlInTemplate, PropertyEntry pse) at System.Web.Compilation.TemplateControlCodeDomTreeGenerator. BuildMiscClassMembers() at System.Web.Compilation.BaseCodeDomTreeGenerator.BuildSourceDataTree() at System.Web.Compilation.BaseTemplateBuildProvider.GenerateCode(AssemblyBuilder assemblyBuilder) at System.Web.Compilation.AssemblyBuilder.AddBuildProvider(BuildProvider buildProvider) --- End of inner exception stack trace --- at System.Web.Compilation.AssemblyBuilder.AddBuildProvider(BuildProvider buildProvider) at System.Web.Compilation.BuildProvidersCompiler.ProcessBuildProviders() at System.Web.Compilation.BuildProvidersCompiler.PerformBuild() at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath) at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) at System.Web.UI.TemplateControl.LoadControl(VirtualPath virtualPath) at System.Web.UI.TemplateControl.LoadControl(String virtualPath) at DotNetNuke.UI.Skins.Skin.InjectModule(Control objPane, ModuleInfo objModule, PortalSettings PortalSettings) --- End of inner exception stack trace --- Eigentlich war alles so weit auch richtig installiert und in einer anderen DNN Installation lief AJAX ohne größere Probleme. Auf dem Rechner war neben ASP.NET 2.0 auch bereits .NET 3.5 installiert und ich dachte mir schon, das es irgendein Konflikt mit den Versionen sein muss. Eine Recherche im Web hat mich dann auf folgendes Ergebnis gebraucht: In der web.config muss der Bereich "runtime" wie folgt angepasst werden:<runtime>      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">        <probing privatePath="bin;bin\HttpModules;bin\Providers;bin\Modules;bin\Support;" />        <dependentAssembly>          <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35" />          <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0" />        </ependentAssembly>        <dependentAssembly>          <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35" />          <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0" />        </dependentAssembly>      </assemblyBinding>    <runtime>  Danach läuft das Modul und die AJAX Funktionen - hier im speziellen das UpdatePanel - wieder ohne Probleme.    

SSLv2 beim Windows Server 2008 deaktivieren (PCI Compliance)

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.