C’è una differenza tra Server.UrlEncode e HttpUtility.UrlEncode?
HttpServerUtility.UrlEncode
utilizzerà HttpUtility.UrlEncode
internamente. Non c’è alcuna differenza specifica. Il motivo dell’esistenza di Server.UrlEncode
è la compatibilità con ASP classico.
Prima ho avuto grattacapi significativi con questi metodi, ti consiglio di evitare qualsiasi variante di UrlEncode
, e invece di usare Uri.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:
Ha anche la documentazione MSDN molto bella “Codifica la porzione di percorso di una stringa URL per una trasmissione HTTP affidabile dal server Web a un client.” – senza effettivamente spiegare cosa fa. Hai meno probabilità di spararti ai piedi con un Uzi …
In breve, attenersi a Uri.EscapeDataString .
Tieni presente che probabilmente non dovresti utilizzare nessuno dei due metodi. La libreria di scripting del sito anti-cross di Microsoft include sostituzioni per HttpUtility.UrlEncode
e HttpUtility.HtmlEncode
che sono più conformi agli standard e più sicure. Come bonus, ottieni anche un metodo JavaScriptEncode
.
Avanti di 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 dell’URL siano WebUtility.UrlEncode (in System.Net
) e Uri. EscapeDataString . A giudicare dalla risposta più popolare qui e altrove, Uri.EscapeDataString sembra essere preferibile. Ma è così? Ho fatto alcune analisi per capire le differenze ed ecco cosa mi è venuto in mente:
WebUtility.UrlEncode
codifica lo spazio come +
; Uri.EscapeDataString
codifica come %20
. Uri.EscapeDataString
percent-encodes !
, (
, )
e *
; WebUtility.UrlEncode
no. WebUtility.UrlEncode
percent-encodes ~
; Uri.EscapeDataString
no. Uri.EscapeDataString
genera una UriFormatException
su stringhe di lunghezza superiore a 65.520 caratteri; WebUtility.UrlEncode
no. ( Un problema più comune di quanto si possa pensare, in particolare quando si tratta di dati di moduli con codifica URL ). Uri.EscapeDataString
genera una UriFormatException
sugli alti caratteri surrogati ; WebUtility.UrlEncode
no. (Questa è una cosa UTF-16, probabilmente molto meno comune.) Ai fini della codifica dell’URL, i caratteri rientrano in una delle 3 categorie: senza riserva (legale in un URL); riservato (legale ma ha un significato speciale, quindi potresti volerlo codificare); e tutto il resto (deve sempre essere codificato).
Secondo la RFC , i caratteri riservati sono:: :/?#[]@!$&'()*+,;=
E i caratteri non riservati sono alfanumerici e -._~
Uri.EscapeDataString definisce chiaramente la sua missione:% -encode tutti i caratteri 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 stranamente ancora codifica quel carattere innocentemente senza riserve.
Pertanto, concordo con il consiglio più diffuso: utilizzare Uri.EscapeDataString quando ansible e capire che i caratteri riservati sono /
come ?
sarà codificato. Se è necessario gestire stringhe potenzialmente di grandi dimensioni, in particolare con i contenuti dei moduli con codifica URL, è necessario ricorrere a WebUtility.UrlEncode e accettarne le stranezze o comunque aggirare il problema.
EDIT: Ho tentato di correggere TUTTE le stranezze sopra menzionate in Flurl tramite i metodi statici Url.Encode
, Url.EncodeIllegalCharacters
e Url.Decode
. Questi sono nel pacchetto principale (che è piccolo e non include tutte le informazioni HTTP), o si sentono liberi di estrarli dalla fonte. Accolgo con favore eventuali commenti / feedback su questi.
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}");
Server.UrlEncode () è lì per fornire la retrocompatibilità con Classic ASP,
Server.UrlEncode(str);
È equivalente a:
HttpUtility.UrlEncode(str, Response.ContentEncoding);
Lo stesso, Server.UrlEncode()
chiama HttpUtility.UrlEncode()