2013-02-27 5 views
17

IIS e ASP.NET (MVC) has some glitches quando si lavora con URL con% -encoding nel percorso (non nella stringa di query, la stringa di query va bene). Come posso aggirare questo? Ad esempio, come posso ottenere l'URL effettivo richiesto?Come posso ottenere in modo affidabile l'URL effettivo, anche quando nel percorso sono presenti parti con codifica percentuale?

Ad esempio, se si dirige verso /x%3Fa%3Db e (separatamente) /x?a=b - entrambi segnalare il .Request.Url come /x?a=b - perché i dati codificati nel percorso viene segnalato in modo errato.

+0

Mentre il pensiero è apprezzato, StackOverflow è * non * un sito frammento o un luogo per pubblicare le cose che capisci, cioè un blog. I timestamp delle vostre domande e risposte indicano che siete venuti qui pronti a postare entrambi. Si prega di inviare solo domande con cui hai veramente bisogno di aiuto. Esistono modi più appropriati per condividere le informazioni con la comunità. –

+29

@ Chris [Self segreteria è sempre stato accettabile] (http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/). Anche la decisione di autorizzare la risposta * come parte della richiesta * è stata presa in modo molto deliberato - quel codice è stato aggiunto molto intenzionalmente. Lo so: lavoro su quella squadra. Inoltre, questo codice è stato condiviso come parte di una richiesta da parte di un utente su "meta" dopo aver corretto un [errore StackOverflow causato da questo problema] (http://meta.stackexchange.com/q/169356). Tl; Dr: rispondere alla tua domanda è esplicitamente OK, a patto che la domanda e la risposta siano ben formate e appropriate. –

risposta

21

Il modo in cui ho virato questo è quello di guardare ai server-variabili sottostanti; la variabile URL contiene un valore decodificato; la variabile QUERY_STRING contiene la query ancora codificata. Non possiamo semplicemente chiamare codificare sulla parte URL, perché anche questo contiene l'originale / ecc nella loro forma originale - se codifichiamo ciecamente l'intera cosa otterremo valori indesiderati %2f; tuttavia, può separarlo e individuare casi problematici:

private static readonly Regex simpleUrlPath = new Regex("^[-a-zA-Z0-9_/]*$", RegexOptions.Compiled); 
private static readonly char[] segmentsSplitChars = { '/' }; 
// ^^^ avoids lots of gen-0 arrays being created when calling .Split 
public static Uri GetRealUrl(this HttpRequest request) 
{ 
    if (request == null) throw new ArgumentNullException("request"); 
    var baseUri = request.Url; // use this primarily to avoid needing to process the protocol/authority 
    try 
    { 
     var vars = request.ServerVariables; 
     var url = vars["URL"]; 
     if (string.IsNullOrEmpty(url) || simpleUrlPath.IsMatch(url)) return baseUri; // nothing to do - looks simple enough even for IIS 

     var query = vars["QUERY_STRING"]; 
     // here's the thing: url contains *decoded* values; query contains *encoded* values 

     // loop over the segments, encoding each separately 
     var sb = new StringBuilder(url.Length * 2); // allow double to be pessimistic; we already expect trouble 
     var segments = url.Split(segmentsSplitChars); 
     foreach (var segment in segments) 
     { 
      if (segment.Length == 0) 
      { 
       if(sb.Length != 0) sb.Append('/'); 
      } 
      else if (simpleUrlPath.IsMatch(segment)) 
      { 
       sb.Append('/').Append(segment); 
      } 
      else 
      { 
       sb.Append('/').Append(HttpUtility.UrlEncode(segment)); 
      } 
     } 
     if (!string.IsNullOrEmpty(query)) sb.Append('?').Append(query); // query is fine; nothing needing 
     return new Uri(baseUri, sb.ToString()); 
    } 
    catch (Exception ex) 
    { // if something unexpected happens, default to the broken ASP.NET handling 
     GlobalApplication.LogException(ex); 
     return baseUri; 
    } 
} 
+2

Amo questo codice, Marc +1. – Brian

Problemi correlati