Server.UrlEncode vs. HttpUtility.UrlEncode


177

C'è una differenza tra Server.UrlEncode e HttpUtility.UrlEncode?

Risposte:


133

HttpServerUtility.UrlEncodeuserà HttpUtility.UrlEncodeinternamente. Non c'è alcuna differenza specifica. Il motivo dell'esistenza di Server.UrlEncodeè la compatibilità con ASP classico.


3
Per quanto riguarda ciò che viene evaso. Internamente chiama questa funzione riferimentiource.microsoft.com/#System/net/System/Net/…
Jeff

Per i lettori: guarda la risposta di Joel Muller qui sotto. Questo è il modo più efficace per codificare URL: stackoverflow.com/a/603962/190476
Sudhanshu Mishra

264

Avevo avuto grossi mal di testa con questi metodi prima, ti consiglio di evitare qualsiasi variante UrlEncodee invece di usareUri.EscapeDataString - almeno quello ha un comportamento comprensibile.

Vediamo...

HttpUtility.UrlEncode(" ") == "+" //breaks ASP.NET when used in paths, non-
                                  //standard, undocumented.
Uri.EscapeUriString("a?b=e") == "a?b=e" // makes sense, but rarely what you
                                        // want, since you still need to
                                        // escape special characters yourself

Ma il mio preferito personale deve essere HttpUtility.UrlPathEncode - questa cosa è davvero incomprensibile. Codifica:

  • "" ==> "% 20"
  • "100% true" ==> "100 %% 20true" (ok, ora l'URL è interrotto)
  • "test A.aspx # anchor B" ==> "test% 20A.aspx # anchor% 20B "
  • "test A.aspx? hmm # anchor B" ==> "test% 20A.aspx? hmm #anchor B " ( notare la differenza con la precedente sequenza di escape! )

Ha anche la documentazione specifica per MSDN "Codifica la parte del percorso di una stringa URL per una trasmissione HTTP affidabile dal server Web a un client." - senza realmente spiegare cosa fa. È meno probabile che ti spari al piede con un Uzi ...

In breve, attenersi a Uri.EscapeDataString .


4
E sfortunatamente ciò non funziona quando si eseguono richieste HTTP su alcuni server Web - Uri.EscapeDataString () non codifica "!" o "'", che differisce dal modo in cui funzionano la maggior parte delle implementazioni del browser di escape () ...
Chris R. Donnelly,

6
! e 'non si suppone che i personaggi siano codificati; ma se un server web buggy lo richiede, è facile aggirare il problema. Evita la funzione di escape di javascript - è intrinsecamente buggy (impossibile da andata e ritorno, per uno). Vedi xkr.us/articles/javascript/encode-compare - ma in breve; puoi invece usare encodeUriComponent (), che si comporta in modo simile a EscapeDataString - codifica in modo prevedibile e reversibile una stringa e inoltre non codifica! e 'personaggi.
Eamon Nerbonne,

2
Questo è vecchio, ma la domanda è stata posta alla prima pagina, quindi ... La parte del percorso di una stringa dell'URL è la parte tra il dominio e il? o # in un URL.
Powerlord il

2
@Tim: ce ne potrebbero essere diversi ?e chi può dire quali devono essere codificati e quali fungono da separatori? Per quanto riguarda lo spazio: in entrambi i casi lo spazio è nell'hash, quindi la presenza o l'assenza di un frammento di query non dovrebbe avere importanza. E infine, è ingiustificabile corrompere un Uri come nel secondo esempio contenente un%. Il UrlPathEncodemetodo è semplice e non dovrebbe mai essere usato.
Eamon Nerbonne,

1
Penso che la mia risposta su stackoverflow.com/a/13993486/237091 possa far luce sull'uso previsto di UrlEncode / UrlPathEncode.
Scott Stafford,

60

Avanti veloce da quasi 9 anni da quando è stato chiesto per la prima volta, e nel mondo di .NET Core e .NET Standard, sembra che le opzioni più comuni che abbiamo per la codifica URL siano WebUtility.UrlEncode (under System.Net) e Uri.EscapeDataString . A giudicare dalla risposta più popolare qui e altrove, Uri.EscapeDataString sembra essere preferibile. Ma è? Ho fatto alcune analisi per capire le differenze ed ecco cosa mi è venuto in mente:

Ai fini della codifica URL, i caratteri rientrano in una delle 3 categorie: senza prenotazione (legale in un URL); riservato (legale ma ha un significato speciale, quindi potresti voler codificarlo); e tutto il resto (deve essere sempre codificato).

Secondo la RFC , i caratteri riservati sono::/?#[]@!$&'()*+,;=

E i personaggi senza prenotazione sono alfanumerici e -._~

Il verdetto

Uri.EscapeDataString definisce chiaramente la sua missione:% -codifica tutti i personaggi riservati e illegali. WebUtility.UrlEncode è più ambiguo sia nella definizione che nell'implementazione. Stranamente, codifica alcuni caratteri riservati ma non altri (perché parentesi e non parentesi ??), e ancora più strano codifica quel ~personaggio innocentemente senza riserve .

Pertanto, concordo con il consiglio popolare: utilizzare Uri.EscapeDataString quando possibile e capire che ai caratteri riservati piacciono /e ?verranno codificati. Se hai bisogno di gestire stringhe potenzialmente grandi, in particolare con il contenuto del modulo con codifica URL, dovrai ricorrere a WebUtility.UrlEncode e accettare le sue stranezze, o altrimenti risolvere il problema.


EDIT: Ho tentato di rettificare TUTTE le stranezze di cui sopra in Flurl attraverso i Url.Encode, Url.EncodeIllegalCharacterse Url.Decodemetodi statici. Questi sono nel pacchetto principale (che è minuscolo e non include tutto il materiale HTTP), o sentiti libero di strapparli dal sorgente. Sono lieto di ricevere qualsiasi commento / feedback in merito.


Ecco il codice che ho usato per scoprire quali caratteri sono codificati in modo diverso:

var diffs =
    from i in Enumerable.Range(0, char.MaxValue + 1)
    let c = (char)i
    where !char.IsHighSurrogate(c)
    let diff = new {
        Original = c,
        UrlEncode = WebUtility.UrlEncode(c.ToString()),
        EscapeDataString = Uri.EscapeDataString(c.ToString()),
    }
    where diff.UrlEncode != diff.EscapeDataString
    select diff;

foreach (var diff in diffs)
    Console.WriteLine($"{diff.Original}\t{diff.UrlEncode}\t{diff.EscapeDataString}");

2
È brillante!
Jorge Aguirre,

1
Ottimo lavoro per verificare la soluzione suggerita sul moderno framework .net.
Neowizard,

Va detto che ci sono alcune differenze tra WebUtility e HttpUtility . WebUtility utilizza lettere maiuscole e HttpUtility utilizza lettere minuscole per entità hexa. Inoltre, HttpUtility non era incluso nelle vecchie versioni dei sottoinsiemi di "Profilo client" di .NET Framework. WebUtility è disponibile da .NET Framework 4.0.
tibx,

28

Tieni presente che probabilmente non dovresti utilizzare uno di questi metodi. La libreria di scripting Anti-Cross Site di Microsoft include sostituzioni per HttpUtility.UrlEncodee HttpUtility.HtmlEncodeche sono entrambe più conformi agli standard e più sicure. Come bonus, ottieni anche un JavaScriptEncodemetodo.


Dopo aver letto la documentazione e le FAQ sul link fornito, credo che questa risposta sia il modo migliore e più sicuro per codificare i dati! Grazie mille per averlo condiviso!
Sudhanshu Mishra,

Il collegamento non funziona più. Quali sono i metodi di sostituzione?
Edward Brey,

@EdwardBrey Questa è l'ultima versione della libreria di scripting del sito Anti-Cross: microsoft.com/en-au/download/details.aspx?id=28589
Sudhanshu Mishra,

11

Server.UrlEncode () è lì per fornire la retrocompatibilità con ASP classico,

Server.UrlEncode(str);

È equivalente a:

HttpUtility.UrlEncode(str, Response.ContentEncoding);

5

Lo stesso, Server.UrlEncode()chiamaHttpUtility.UrlEncode()

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.