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.

Freitag, 20. April 2012

ASP.NET MVC: Content bei 4xx Antworten zurückgeben

Wenn man in einer Action einen HTTP-Fehler generiert, dann setzt der IIS als Content immer seine Standardmeldung.

Beispiel:
public ActionResult MyAction()
{
    Response.StatusCode = 409; // Conflict
    return Content("A steht mit B im Konflikt!", "text/plain")
}

Die Antwort die man beim Abruf der Action kriegt ist nicht wie zu erwarten "A steht mit B im Konflikt!", sondern "Seite kann aufgrund eines Konfliktes nicht angezeigt werden", wobei die Sprache der Meldung abhängig Ländereinstellung des Servers ist.

Die Lösung: Response.TrySkipIisCustomErrors = true;
public ActionResult MyAction()
{
    Response.StatusCode = 409; // Conflict
    Response.TrySkipIisCustomErrors = true;
    return Content("A steht mit B im Konflikt!", "text/plain")
}

Freitag, 16. März 2012

git+putty: fatal: The remote end hung up unexpectedly

Wenn git beim Zugriff auf ein Repository via SSH (mittels plink) den Fehler "fatal: The remote end hung up unexpectedly" meldet kann dies auch daran liegen, dass man eine Putty-Session hat die wie die URL des Repositories heißt.

Ist die URL z.B. ssh://git.mydomain.com/reponame.git, dann darf man keine Putty-Session mit dem Namen git.mydomain.com haben, da sonst obiger Fehler auftritt.