Donnerstag, 1. Dezember 2011

Spaß mit QueryString

Einen QueryString zu ändern kann gar nicht so leicht sein. Beispielsweise ist Request.QueryString readonly. Daher kann man nicht einfach Request.QueryString.Remove("parameterDerMichStoert") aufrufen.

Eine Option ist es Request.QueryString.ToString() zu verwenden und dann dem ganzen mit regulären Ausdrücken zu Leibe zu rücken. Es gibt aber eine IMHO schönere Möglichkeit. Man kopiert sich einfach die Werte in eine NameValueCollection
var nameValueCollection = new NameValueCollection(Request.QueryString);
nameValueCollection.Remove("page");
Falls man den QueryString schon in string-Form vorliegt, kann mit HttpUtility.ParseQueryString(...) eine entsprechende NameValueCollection erstellt werden.

Bleibt allerdings noch ein Problem. Die ToString()-Methode von NameValueCollection liefert uns keinen QueryString. Im Netz finden sich viele Extension-Methods die behaupten dies zu können, allerdings waren alle die ich gefunden habe fehlerhaft. Das Problem waren immer mehrfache Werte für einen Parameter. Anstatt z.B. "customerId=1&customerId=2" haben die Methoden "customerId=1,2" ausgegeben.

Genug gelabert, hier die Extension-Method:
public static string ToQueryString(this NameValueCollection nameValueCollection)
{
 var parts = new Collection();
 foreach (string name in nameValueCollection)
 {
     var values = nameValueCollection.GetValues(name);
     if (values == null) continue;
     foreach(var value in values)
     {
         parts.Add(string.Format("{0}={1}", name, HttpUtility.UrlEncode(value)));
     }
 }
 return String.Join("&", parts);
}

Server.MapPath() mal anders

Server.MapPath(...) ist bekanntlich eine praktische Methode, um in Controllern und Views physische Pfade für Assets zu bestimmen.

Und wenn man kein Server-Objekt hat?

Sofern der Code im Rahmen eines Requests ausgeführt wird kann man einfach über den HttpContext gehen:

HttpContext.Current.Server.MapPath(...)

Was aber, wenn man z.B. in einem statischen Konstruktor oder sonst wie außerhalb eines Requests einen Pfad bestimmen muss. Auch hier gibt es eine Lösung:

HostingEnvironment.MapPath(...)

Prinzipiell könnte man wohl an allen Stellen an denen man Server.MapPath(...) verwendet auch HostingEnvironment.MapPath(...) nehmen.