ASP.NET erzeugt permanent eine neue SessionId

Bei der Verwendung von Session bzw. genauer der SessionId als Kennzeichner für z.B. eine eindeutigen Benutzer (Browser) über seinen Lebenszyklus, muss man die Eigenart bzw. die Behandlung von Sessions innerhalb von ASP.NET kennen. Bei der Verwendung von cookie-based session state wird von ASP.NET bei jedem Request eine neue SessionId erzeugt, bis der erste Wert in der Session gespeichert wurde.  Das ist sehr wichtig zu wissen, denn sonst ist die SessionId nicht als eindeutiger Kennzeichner zu benutzen. (Wie sinnvoll das generell ist, sei jetzt hier mal nicht berücksichtigt). Es reicht also z.B. in der global.ascx folgenden Code hinzufügen: void Session_Start(object sender, EventArgs e) { HttpContext.Current.Session.Add("SomeValue", string.Empty); } Damit hat die Session immer eine Wert und behält somit die SessionId bis die Session ausläuft. Weitere Informationen findet man dazu auch hier.

HttpWebRequest: Den basic http authentication header erzwingen

Um in .NET http web request zu realisieren ist die Klasse HttpWebRequest aus dem .NET Framework ist sehr komfortabel. Diese unterstützt auch die Möglichkeit Authentication Informationen im Header mitzusenden. Hier ein vereinfachtes Beispiel dafür var webRequest = (HttpWebRequest)WebRequest.Create(url); webRequest.Credentials = new NetworkCredential(userName, password); Nun ist es allerdings so, dass diese Informationen nicht direkt als http Header mitgesendet werden sondern erst auf Anfrage von Server / Service bei einem weiteren Request hinzugefügt werden. Um zu erreichen das der http basic authentcation header immer mitgesendet wird kann man folgenden Code verwenden: public void SetBasicAuthHeader(WebRequest httpRequest, String userName, String userPassword) { var authHeader = Convert.ToBase64String(Encoding.Default.GetBytes(userName + ":" + userPassword)); httpRequest.Headers["Authorization"] = "Basic " + authHeader; } Damit wird der Header direkt beim ersten Aufruf mitgesendet.

Die web.config bei der Installation eines Modules verändern

Je nach Modul gibt es schon mal die Anforderung, dass neue Einträge in die web.config geschrieben werden müssen. Dieses kann man entweder im SourceCode erledigen oder aber die Änderungen in dem DNN Modul Manifest / Definitionsdatei (meinmodule.dnn) definieren. Verfügbar ist das ab der Version 5 von DotNetNuke. Um das zu nutzen, muss man in der Manifest-Datei folgendes hinzufügen:<component type="Config"> <config> <configFile>web.config</configFile> <install> <configuration> <nodes>             ..... </nodes> </configuration> </install> <uninstall> <configuration> <nodes /> </configuration> </uninstall> </config> </component>Wie man sieht gibt es zwei Bereiche. Der Bereich <install> wird während der Installation und der Bereich <uninstall> wird be der Deinstallation von dem DNN Modul ausgeführt.Innerhalb des Tags <nodes> können dann die entsprechenden Einträge hinzugefügt werden. Hier ein Beispiel womit ein HttpHandler hinzugefügt wird:<node path="/configuration/system.web/httpHandlers" action="update" key="path" collision="overwrite"> <add verb="*" path="myhandler.axd" validate="false" type="DNN.Module.Shop.MyHandler, DNN.Module.Shop" /> </node>Weiter Informationen findet man im Wiki auf www.dotnetnuke.com

Automapper custom TypeConverter Exceptionhandling

In einem Projekt verwende ich aktuell die Komponente AutoMapper (automapper.codeplex.com), im zwischen den externen Datacontracts und den internen Entities zu mappen. Teilweise habe ich dafür auch eigenen TypeConverter entwickelt. Wenn man in diesem TypeConverter eine eigene Exception auslöst, dann erhält man beim aufrufenden Code immer eine AutoMapperMappingException.Da ich in dem Projekt ein globales ErrorHandling habe (WCF bzw. Implementierung vom IErrorHandler), möchte ich aber die konkrete Exception gerne aus dem TypeConverter in mein Errorhandling weitergeben. Damit das funktioniert baut man sich am besten einen Wrapper für den Aufruf vom Automapper, um dort zu entscheiden, welche Exception man weitergeben möchte. Die eigene Exception wird als InnerException vom AutoMapperMappingException mitgeliefiert. Durch überprüfung der InnerException kann man als feststellen, wie die aktuelle Exception zu bahandeln ist.Hier ein Beispiel: public class AutoMapperWrapper { public static U Map<T, U>( T source) { try { return Mapper.Map<T, U>(source); } catch (Exception e) { while (e is AutoMapperMappingException) e = e.InnerException; if (e == null) throw; else throw e; } } }

Install ASP.NET 1.1 with IIS7 on Windows 2008

In einer Evaluierungsphase habe ich gerade mal probiert eine alte ASP.Net 1.1 Anwendung auf einem Windows Server 2008 zu installieren. Per Default wird allerdings ASP.NET 1.1 nicht mehr auf einem Windows 2008 Server unterstützt, so das ein wenig manuelle Arbeit notwendig ist.Als erstes muss man die "IIS Metabase Compatibility" installieren und das geht durch die Schritte: "Start" -> "Server Manager" ->  "Manage Roles" -> "Web Server (IIS)" -> "Add Role Services".  Der zweite Schritt ist die Installation vom .Net Framework 1.1. Hier die Downloadlinks:.NET Framework Version 1.1 Redistributable Package.NET Framework Version 1.1 Service Pack 1ASP.NET Security Update for .NET Framework 1.1 SP1Wenn man das Setup ausführt, dann bekommt man vom Windows Server 2008 den Hinweis das es möglicherweise Kompatibilitätsprobleme geben könnte. Diese Meldung einfach mit "Ausführen" / "run programm" überspringen.Anschließend muss das alte .Net Framework noch im IIS registriert werden. Dafür kann man folgenden Behfel ausführen:%windir%\Microsoft.NET\Framework\v1.1.4322\aspnet_regiis -enableEin Änderung in der machine.config (unter %windir%\Microsoft.NET\Framework\v1.1.4322\config\machine.config) muss noch gemacht werden. Vor dem schließenden Tag </configSection> muss folgendes hinzhugefügt werden:<section name="system.webServer" type="System.Configuration.IgnoreSectionHandler,    System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />Einen neue ApplicationPool - der unter .Net 1.1 läuft - kann man nun mit folgendem Befehl anlegen:%windir%\system32\inetsrv\appcmd add apppool /name:"Pool1-1"  /managedRuntimeVersion:"v1.1" Bei einem 64bit Betriebsystem muss man nun noch ein Verzeichnis erstellen:md %windir%\Microsoft.net\Framework64\v1.1.4322\config undcopy %windir%\Microsoft.net\Framework\v1.1.4322\Config\machine.config %windir%\Microsoft.net\Framework64\v1.1.4322\config\machine.config

WCF URL Rewriting entfernen der Endung "svc"

Bei dem Standardverhalten, wenn ein WCF Service über den IIS veröffentlicht wird ist, dass der Endpunkt die Datei von Service ist mit der Dateiendung ".svc". Dieses sieht aber - gerade im Bezug auf ein REST-basiertes System nicht besonders elegant aus. Bei dem Einsatz von IIS 7.0 ist es sehr einfach die Dateiendung zu entfernen, ohne dabei viel Code zu schreiben. Für das URL Rewriting gibt eine Erweiterung, die man dem IIS 7.0 hinzufügen kann. Dadurch ist es sehr schön möglich z.B. über Regular Expressions ein URL Rewriting durchzuführen. Nach der Installation dieser Erweiterung muss nur noch folgende Regel definiert werden:1. Name: Entfernen der Dateiendung svc2. Request URL: Matches the pattern3. Using: Regular Expressions4. Pattern: ^([0-9a-zA-Z\-]+)/([0-9a-zA-Z\-\.\/\(\)]+) 5. Ignore Cases: true6. Action Type: Rewrite7. Rewrite URL: {R:1}.svc/{R:2}8. Append Querystring: trueFertig ;-)Per Eintrag in der web.config sieht das dann alternativ so aus:  <system.webServer>    <modules runAllManagedModulesForAllRequests="true" />        <rewrite>            <rules>                <rule name="Remove Svc Extension">                    <match url="^([0-9a-zA-Z\-]+)/([0-9a-zA-Z\-\.\/\(\)]+)" />                    <action type="Rewrite" url="{R:1}.svc/{R:2}" />                </rule>            </rules>        </rewrite>  </system.webServer>

WCF, IIS and 404.3 Errors

Nachdem ich an einem jungfräulichen Rechner sitze und gerade einen WCF Service debuggen wolte, bekam ich ständig vom IIS den Fehlercode 404.3. Schnell habe ich herausgefunden das die verwendete Endung ".svc" nicht einem Handler zugeordnet ist. Um dieses aber nicht manuel machen zu müssen gibt es bei der WCF ein Tool, dass die Registrierung übernimmt. Das Tool findet man unter %Windows%\Microsoft.Net\Framework\v3.0\Windows Communication Foundation\ und heißt ServiceModelReg.exe. Das muss mit dem Parameter "-i" aufgerufen werden und anschließend funktioniert auch das Hosting im IIS.

Open-Source e-mail templating engine

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.

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.

iPhone Apps mit Microsoft .NET entwickeln

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

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

Neuer DotNetNuke FCK-Plugin zur Nutzung von token-replacement

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!

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

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

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.

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.

AnkhSVN: Subversion Client AddOn Microsoft Visual Studio 2005, 2008

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.

Visual Studio 2005 VS 2008 SP1 Authentifizierungsfehler beim Debuggen

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.