Donnerstag, 26. September 2013

NuGet Package Manager Console funktioniert nicht

Wenn die NuGet Console statt dem üblichen Prompt
PM>
sowas
PS C:\Das\Solution\Verzeichnis>
anzeigt, dann ist dies wohl dieser Bug. Was bei mir geholfen hat ist bei geöffneter Konsole die Solution zu schließen und anschließend Visual Studio zu beenden. Dann startet man Visual Studio ohne direkt ein Projekt/Solution zu laden und warten mit dem öffnen des Projekts sich die NuGet-Konsole initialisiert hat.

Mittwoch, 3. Juli 2013

DateTime Probleme bei JSON-Konvertierung mittels JavaScriptSerializer

Mit dem JavaScriptSerializer stellt Microsoft freundlicherweise eine Möglichkeit bereit .NET-Objekte in JSON umzuwandeln. Ebenfalls großartig ist das man mit damit auch aus JSON wieder ein .NET-Objekt erzeugen kann. Weniger großartig ist folgendes:

var now = DateTime.Now;

var s = new JavaScriptSerializer(); 
var serialized = s.Serialize(now);  
var notNow = s.Deserialize<DateTime>(serialized);

Denn sofern man nicht UTC als Zeitzone verwendet sind now und notNow nicht gleich. Gewissermaßen sind sie schon gleich weil now.Kind == DateTimeKind.Local und notNow = DateTimeKind.Utc ist und beide den selben Zeitpunkt beschreiben. Intuitiv ist es aber nicht.

Vielleicht sollte Serialize() standardmäßig eine Exception werfen, wenn es auf ein DateTime stößt, dass keine UTC-Zeit beschreibt. Dann könnte man vielleicht über s.AllowLocalDateTimes = true dieses Verhalten steuern. So wäre man beim Programmieren gezwungen sich darüber Gedanken zu machen, mit was für DateTimes man arbeitet.

Mittwoch, 29. August 2012

Kenne dein Framework - TypeConverter

Auch wenn wenn wir in der .NET bzw. ASP.NET MVC-Welt dank EntityFramework und ModelBinder nicht mehr so oft gezwungen sind Strings manuell in Zahlen- und Wahrheitswerte umwandeln zu müssen, kommt es hin und wieder dann doch vor.

Wenn man nun weiß, dass die Strings immer zu - sagen wir mal - Decimals umgewandelt werden müsste bietet sich natürlich Convert.ToDecimal(derWertAlsString) an. Manchmal muss weiß man aber erst zur
Laufzeit mit was für Typen man zu tun hat, hier bieten sich TypeConverter an.

Hier ein Beispiel wie so etwas aussehen kann:
var stringValue = "1234";
Type type = GetTypeAtRuntime(...);
var converter = TypeDescriptor.GetConverter(type);
var obj = converter.ConvertFrom(stringValue);
Wobei GetTypeAtRuntime() dann entsprechend sinnvoll zu implementieren ist.

Mittwoch, 4. Juli 2012

SQL Server - Unbenutzten Speicherplatz wieder freigeben nach 'Drop Column'

Nachdem man eine Tabelle theoretisch verkleinert hat, indem man z.B eine Spalte gelöscht hat oder den Datentyp einer Spalte geändert hat, hat das für den belegten Speicherplatz erstmal null Effekt. Es ist für den SQL Server nur eine Änderung der Metadaten. Dies kann man überprüfen indem man sich z.B. die Ausgaben von
DBCC SHOWCONTIG( tablename)
oder
exec sp_spaceused 'tablename'
anschaut.
Wenn die entsprechende Tabelle einen Clustered Index hat, kann man mit
DBCC DBREINDEX( tablename)
dafür sorgen, dass der überflüssige Speicher freigegeben wird. Weitere Infos dazu findet man hier: http://sqlblogcasts.com/blogs/tonyrogerson/archive/2007/08/27/alter-table-drop-column-does-not-reclaim-the-space-the-column-took-it-s-a-meta-data-change-only.aspx

Freitag, 18. Mai 2012

Geokoordinaten im Entity Framework 5 und SQL Server

Wieder was gelernt. Wenn direkt auf dem SQL-Server eine Punktkoordinate die in Hamburg liegt erzeugt, macht man dies z.B. so:

geography::Point(53.566366364562107, 9.98555839061737, 4326)

Man gibt also der Point-Funktion also erst die Breite dann die Länge. Nutzt man aber die Geofunktionen von Entity Framework 5 (oder neuer) werden die Koordinaten im "Well-known text"-Format angegeben, hier gilt erst der Längengrad, dann der Breitengrad. Beispiel:

DbGeography.FromText("POINT(9.98555839061737 53.566366364562107)", 4326);

Montag, 7. Mai 2012

IIS Directory Security, und wo kommt die ApplicationPoolIdentity her?

Wenn man manuell ein Verzeichnis anlegt, um dieses später als Root Verzeichnis einer Website im IIS zu nutzen, gibt es ein paar "rechtliche" Dinge zu beachten. Wenn man die Site über den IIS Manager hinzufügt, und aus dem Dialog heraus einen neuen Ordner für die Site erstllen lässt, hat man diese Rechteprobleme üblicherweise nicht, aber auch das ist nicht garantiert.

Nachdem man also das Verzeichnis angelegt hat, sind die Rechte erstmal ziemlich spärlich gesät:


So wird es nach Einrichtung der Site im IIS, beim Aufruf erstmal einen 500er geben, da z.B. die web.config überhaupt nicht gelesen werden kann. Es ist notwendig, ApplicationPool die entsprechenden Rechte zu geben. Der User unter dem das ApplicationPool läuft, ist standardmäßig die ApplicationPoolIdentity. Diese wird man aber vergeblich im Explorer Dialog beim Hinzufügen der Rechte suchen. Es handelt sich um einen "dynamischen" User, dessen Namen man kennen muss. Im Falle des "ASP.NET v4.0" AppPools, heißt der entsprechende User "IIS AppPool\ASP.NET v4.0":


Der Name der AppPoolIdentity lässt sich in der Konsole über
%systemroot%\System32\inetsrv>appcmd.exe list app /site.name:"your.site.name"
abfragen. Auch im IIS Manager kann man sich den Namen anzeigen lassen. Letztendlich sind dann noch die Gruppen IUSR und IIS_IUSRS wichtig, damit der Zugriff auf die Site korrekt funktioniert. Diese kann man bequem über den Explorer Dialog hinzufügen.




Eine sehr gute Beschreibung der verschiedenen relevanten Benutzer und Gruppen findet sich hier: http://stackoverflow.com/questions/5729264/what-are-all-the-user-accounts-for-iis-asp-net-and-how-do-they-differ Dort ist auch der nötige Befehl zum Hinzufügen der Rechte für die ApplicationPoolIdentity nochmal beschrieben.

Freitag, 4. Mai 2012

Mehrere Sites im IIS 7 ohne Wildcard Zertifikat an https binden

Bei der Verwendung eines Nicht-Wildcard SSL Zertifikats im IIS 7, hat man leider keine Möglichkeit das Bindung von einem Hostheader abhängig zu machen. Der Konfigurationsdialog lässt keine entsprechende Eingabe zu:
Man hat aber die Möglichkeit mit einem kleinen Trick, die Eingabe des Hostnamens zuzulassen. Dazu wie folgt vorgehen:
Launch the Microsoft Management Console (MMC)
Select Start –> Run
Type in “MMC” and hit enter
From the console, select File –> Add / Remove Snap-in
Select Certificates from the Add / Remove dialog
Select Computer Account when prompt for which certificates the snap-in will manager.
Select Local Computer when prompted
Click OK to add the Snap-in to the MMC
Locate your SSL certificate
For self-signed (SELFSSL), look in Personal
For installed / purchased, look in the appropriate folder the certificate was originally installed in
Right click on the certificate and select properties
Edit the Friendly Name field so the name starts with an *
Der Dialog in der Management Konsole sieht folgendermaßen aus:


Wenn man anschließend im IIS die https Bindung hinzufügt und das entsprechende Zertifikat auswählt hat man auch die Möglichkeit den Hostnamen einzutragen. Der IIS nimmt durch den * am Anfang des Anzeigenamens des Zertifikats an, dass es sich um ein Wildcard Zertifikat handelt.

Zwar bekommt man im Browser natürlich eine Fehlermeldung, da der Zertifikatname nicht mit dem Servernamen übereinstimmt, aber trotzdem kann man auf diese Weise ein Nicht-Wildcard Zertifikat dazu verwenden, mehrere Sites im IIS 7 an eine IP über https zu binden.