Risposte:
HttpServerUtility.UrlEncodeuserà HttpUtility.UrlEncodeinternamente. Non c'è alcuna differenza specifica. Il motivo dell'esistenza di Server.UrlEncodeè la compatibilità con ASP classico.
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:
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 .
?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.
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:
WebUtility.UrlEncodecodifica lo spazio come +; Uri.EscapeDataStringlo codifica come %20.Uri.EscapeDataStringcento-codifica !, (, ), e *; WebUtility.UrlEncodenon.WebUtility.UrlEncodecodifica percentuale ~; Uri.EscapeDataStringnon.Uri.EscapeDataStringgenera UriFormatExceptionstringhe su più lunghe di 65.520 caratteri; WebUtility.UrlEncodenon. ( Un problema più comune di quanto si possa pensare, in particolare quando si tratta di dati di moduli con codifica URL .)Uri.EscapeDataStringgetta una UriFormatExceptionsui caratteri surrogati alti ; WebUtility.UrlEncodenon. (Questa è una cosa UTF-16, probabilmente molto meno comune.)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 -._~
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}");
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.