C# ASP.NET Abfrage-Zeichenfolge-Parser


7

Wenn Sie wurden für eine schöne und saubere Weise suchen, Ihre Query-String-Werte zu analysieren, ich habe mit diesem kommen:

/// <summary> 
    /// Parses the query string and returns a valid value. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="key">The query string key.</param> 
    /// <param name="value">The value.</param> 
    protected internal T ParseQueryStringValue<T>(string key, string value) 
    { 
     if (!string.IsNullOrEmpty(value)) 
     { 
      //TODO: Map other common QueryString parameters type ... 
      if (typeof(T) == typeof(string)) 
      { 
       return (T)Convert.ChangeType(value, typeof(T)); 
      } 
      if (typeof(T) == typeof(int)) 
      { 
       int tempValue; 
       if (!int.TryParse(value, out tempValue)) 
       { 
        throw new ApplicationException(string.Format("Invalid QueryString parameter {0}. The value " + 
                   "'{1}' is not a valid {2} type.", key, value, "int")); 
       } 
       return (T)Convert.ChangeType(tempValue, typeof(T)); 
      } 
      if (typeof(T) == typeof(DateTime)) 
      { 
       DateTime tempValue; 
       if (!DateTime.TryParse(value, out tempValue)) 
       { 
        throw new ApplicationException(string.Format("Invalid QueryString parameter {0}. The value " + 
                 "'{1}' is not a valid {2} type.", key, value, "DateTime")); 
       } 
       return (T)Convert.ChangeType(tempValue, typeof(T)); 
      } 
     } 
     return default(T); 
    } 

Ich habe immer so etwas haben wollte und schließlich haben es richtig ... zumindest glaube ich so ...

Der Code sollte selbsterklärend sein ...

Kommentare oder Vorschläge zu machen, ist es besser geschätzt werden.

  0

Vielleicht behandeln Sie es früher in Ihrem Code-Stack, aber denken Sie daran, dass ein Schlüssel mehrere Werte in einem Querystring haben kann, dh x = 1,2,3 22 feb. 092009-02-22 15:58:07

  0

@jro Ich würde den Fall mit mehreren Werten für ungültig halten, da so weit der Querystring betrifft seinen einzigen Wert, eine Zeichenkette von "1,2,3", die ihn als irgendeinen parsiert etwas anderes wäre nicht korrekt. 06 mai. 112011-05-06 13:37:25

5

Angesichts der Tatsache, dass Sie nur drei verschiedene Arten behandeln, würde ich stattdessen drei verschiedene Methoden vorschlagen - generische Methoden sind am besten, wenn sie gut mit jedem Typ Argument arbeiten, das von den Typ-Einschränkungen erlaubt ist.

Darüber hinaus würde ich dringend empfehlen, dass für int und DateTime Sie die Kultur angeben verwenden - es sollte nicht wirklich von der Kultur abhängig der Server in sein geschieht (Wenn Sie Code haben die Kultur der erraten. Benutzer, Sie könnten das stattdessen verwenden.) Schließlich würde ich auch empfehlen, eine gut spezifizierte Menge von DateTime Formaten zu unterstützen, anstatt nur was TryParse standardmäßig unterstützt. (Ich ziemlich viel immer Verwendung ParseExact/TryParseExact statt Parse/TryParse.)

Beachten Sie, dass die String-Version nicht wirklich etwas tun müssen, da value ist bereits ein String (obwohl Ihre aktuellen Code konvertiert " "zu null, die möglicherweise oder nicht sein können, was Sie wünschen).

  0

+1 für ParseExact/TryParseExact, insbesondere, da Sie ein Array von Formaten übergeben können. 22 feb. 092009-02-22 13:25:07


1

Es scheint mir, dass Sie eine Menge untypische Typumwandlungen machen. Die tempValue-Variablen sind sehr wichtig für den Typ, den Sie zurückgeben möchten. Ebenso ist der Wert im String-Case bereits ein String, also gib ihn stattdessen zurück.


2

In meiner Anwendung habe ich die folgende Funktion wurde unter Verwendung von: -

public static class WebUtil 
{ 
    public static T GetValue<T>(string key, StateBag stateBag, T defaultValue) 
    { 
     object o = stateBag[key]; 

     return o == null ? defaultValue : (T)o; 
    } 
} 

Die erforderliche Standard-zurückgegeben, wenn der Parameter nicht geliefert hat, wird der Typ abgeleitet von default und Gießen Ausnahmen werden nach Bedarf angehoben .

Verwendung ist wie folgt: -

var foo = WebUtil.GetValue("foo", ViewState, default(int?)); 

34

Eine einfache Art und Weise zu analysieren (wenn Sie Typkonvertierungen tun nicht wollen) ist

HttpUtility.ParseQueryString(queryString); 

Sie Abfragezeichenfolgeflag von einer URL mit

extrahieren
+4

Dies funktioniert nur, wenn URL eine vollständige URL ist. Wenn Sie eine relative URL haben, wird das Query-Mitglied von Uri nicht unterstützt. 27 mär. 112011-03-27 23:46:49


3

Ich habe die folgende Methode geschrieben, um den QueryString zu stark typisierten Werten zu analysieren:

public static bool TryGetValue<T>(string key, out T value, IFormatProvider provider) 
{ 
    string queryStringValue = HttpContext.Current.Request.QueryString[key]; 

    if (queryStringValue != null) 
    { 
     // Value is found, try to change the type 
     try 
     { 
      value = (T)Convert.ChangeType(queryStringValue, typeof(T), provider); 
      return true; 
     } 
     catch 
     { 
      // Type could not be changed 
     } 
    } 

    // Value is not found, return default 
    value = default(T); 
    return false; 
} 

Anwendungsbeispiel:

int productId = 0; 
bool success = TryGetValue<int>("ProductId", out productId, CultureInfo.CurrentCulture); 

Für eine Abfragezeichenfolgeflag von ?productId=5 die bool wahr wäre und int productId würde 5 entsprechen.

Für eine Abfragezeichenfolgeflag von ?productId=hello die bool falsch und int productId 0.

die bool falsch wäre entspräche und int productId 0.


0

auf Ronalds answer Basierend Für eine Abfragezeichenfolgeflag von ?noProductId=notIncluded wäre ich aktualisiert entspräche haben meine eigene Querystring-Parsing-Methode. Die Art, wie ich es verwende, besteht darin, es als eine Erweiterungsmethode für das Page-Objekt hinzuzufügen, so dass es für mich einfach ist, Querystring-Werte und -Typen zu überprüfen und umzuleiten, wenn die Seitenanforderung nicht gültig ist.

Die Erweiterung Methode sieht wie folgt aus:

public static class PageHelpers 
{ 
    public static void RequireOrPermanentRedirect<T>(this System.Web.UI.Page page, string QueryStringKey, string RedirectUrl) 
    { 
     string QueryStringValue = page.Request.QueryString[QueryStringKey]; 

     if(String.IsNullOrEmpty(QueryStringValue)) 
     { 
      page.Response.RedirectPermanent(RedirectUrl); 
     } 

     try 
     { 
      T value = (T)Convert.ChangeType(QueryStringValue, typeof(T)); 
     } 
     catch 
     { 
      page.Response.RedirectPermanent(RedirectUrl); 
     } 
    } 
} 

Das bin ich Dinge tun können wie folgt aus:

protected void Page_Load(object sender, EventArgs e) 
{ 
    Page.RequireOrPermanentRedirect<int>("CategoryId", "/"); 
} 

dann kann ich den Rest meines Code schreiben, und verlassen sich auf die Existenz und die korrekte Format des Querystring-Elements, so dass ich es nicht jedes Mal testen muss, wenn ich darauf zugreifen möchte.

Hinweis: Wenn Sie Sie vor .net 4 dann verwenden wollen auch die folgenden RedirectPermanent Erweiterungsmethode:

public static class HttpResponseHelpers 
{ 
    public static void RedirectPermanent(this System.Web.HttpResponse response, string uri) 
    { 
     response.StatusCode = 301; 
     response.StatusDescription = "Moved Permanently"; 
     response.AddHeader("Location", uri); 
     response.End(); 
    } 
} 

2

Dies ist eine alte Antwort, aber ich habe folgendes getan:

  string queryString = relayState.Split("?").ElementAt(1); 
      NameValueCollection nvc = HttpUtility.ParseQueryString(queryString);