Czy C # ma odpowiednik encodeURIComponent () w języku JavaScript?

142

W JavaScript:

encodeURIComponent("©√") == "%C2%A9%E2%88%9A"

Czy istnieje odpowiednik dla aplikacji C #? Do ucieczki znaków HTML użyłem:

txtOut.Text = Regex.Replace(txtIn.Text, @"[\u0080-\uFFFF]",
    m => @"&#" + ((int)m.Value[0]).ToString() + ";");

Ale nie jestem pewien, jak przekonwertować dopasowanie do prawidłowego formatu szesnastkowego używanego przez JS. Na przykład ten kod:

txtOut.Text = Regex.Replace(txtIn.Text, @"[\u0080-\uFFFF]",
    m => @"%" + String.Format("{0:x}", ((int)m.Value[0])));

Zwraca „ %a9%221a"for "©√"zamiast "%C2%A9%E2%88%9A". Wygląda na to, że muszę podzielić ciąg na bajty lub coś w tym stylu.

Edit: To jest dla aplikacji Windows, tylko pozycje dostępne w System.Webto: AspNetHostingPermission, AspNetHostingPermissionAttribute, i AspNetHostingPermissionLevel.

Travis
źródło

Odpowiedzi:

225

Uri.EscapeDataStringlub HttpUtility.UrlEncodejest prawidłowym sposobem zmiany znaczenia dla ciągu znaków, który ma być częścią adresu URL.

Weźmy na przykład ciąg "Stack Overflow":

  • HttpUtility.UrlEncode("Stack Overflow") -> "Stack+Overflow"

  • Uri.EscapeUriString("Stack Overflow") -> "Stack%20Overflow"

  • Uri.EscapeDataString("Stack + Overflow")-> Koduje również "+" to "%2b"---->Stack%20%2B%20%20Overflow

Tylko ostatnie jest poprawne, gdy jest używane jako rzeczywista część adresu URL (w przeciwieństwie do wartości jednego z parametrów ciągu zapytania)

Steve
źródło
Głównym problemem, który miałem, był brak odniesienia do System.Web w moim rozwiązaniu, ale nie wiedziałem o EscapeUriString, dzięki!
travis,
56
W przeciwieństwie do encodeURIComponent (), Uri.EscapeUriString () nie koduje „+” do „% 2b”. Zamiast tego użyj Uri.EscapeDataString ().
jwaliszko
4
Użyj WebUtility zamiast HttpUtility, aby uniknąć konieczności odwoływania się do System.Web. HttpUtility nie istnieje w .NET Core.
Steven De Kock
2
@Steve Czy rozważyłbyś pogrubienie ostatniego akapitu? Wydaje się, że jest to najważniejsza rzecz, którą należy wiedzieć na tej stronie i wymaga większej widoczności.
Timo
Zobacz również tę odpowiedź, aby uzyskać więcej wyjaśnień na temat różnicy między Uri.EscapeUriString i Uri.EscapeDataString: stackoverflow.com/questions/4396598/ ...
Jason
21

HttpUtility.HtmlEncode/ Decode
HttpUtility.UrlEncode/ Decode

Możesz dodać odwołanie do System.Webzestawu, jeśli nie jest dostępne w Twoim projekcie

David Thibault
źródło
Powinienem był być bardziej szczegółowy: dotyczy to aplikacji systemu Windows, jedynymi elementami dostępnymi w System.Web są: AspNetHostingPermission, AspNetHostingPermissionAttribute i AspNetHostingPermissionLevel.
travis
5
Możesz dodać odniesienie do zestawu System.Web
David Thibault,
2
HtmlEncoding to zupełnie inna rzecz. UrlEncode to pozbawiony sensu interfejs API, którego nigdy nie należy używać. Nie ma sensu kodowanie całego adresu URL (chyba że faktycznie chcesz zakodować jego wartość jako parametr - ale to nie jest to, co to robi). Celem kodowania / ucieczki jest to, że przekazujesz, że zastrzeżony znak powinien zostać przepuszczony bez jego zwykłego znaczenia (np.? Identyfikuje zapytanie lub & oddziela parametry zapytania). Wymaga to wiedzy, której UrlEncode nie ma i nie może mieć.
Brandon Paddock
18

Próbowałem zrobić w pełni kompatybilny analog z encodeURIComponent javascript dla C # i po moich 4-godzinnych eksperymentach znalazłem to

C # KOD:

string a = "!@#$%^&*()_+ some text here али мамедов баку";
a = System.Web.HttpUtility.UrlEncode(a);
a = a.Replace("+", "%20");

wynik to: !% 40% 23% 24% 25% 5e% 26 * () _% 2b% 20some% 20text% 20here% 20% d0% b0% d0% bb% d0% b8% 20% d0% bc% d0% b0% d0% bc% d0% b5% d0% b4% d0% be% d0% b2% 20% d0% b1% d0% b0% d0% ba% d1% 83

Po zdekodowaniu go za pomocą funkcji decodeURLComponent () JavaScript;

otrzymasz to :! @ # $% ^ & * () _ + tekst tutaj али мамедов баку

Dziękuję za uwagę

Ali Mamedov
źródło
2
Działa, ale możesz po prostu użyć Uri.EscapeDataString("!@#$%^&*()_+ some text here али мамедов баку")zamiast tego.
mklement0
Właściwie Uri.EscapeDataStringkoduje znaki „(” i „)”, podczas gdy HttpUtility.UrlEncodenie.
Øystein Kolsrud,
12

System.Uri.EscapeUriString () najwyraźniej nic nie zrobił, ale System.Uri.Escape Data String () działał dla mnie.

Echilon
źródło
10

Spróbuj Server.UrlEncode()lub System.Web.HttpUtility.UrlEncode()w przypadku, gdy nie masz dostępu do Serverobiektu. Możesz również użyć, System.Uri.EscapeUriString()aby uniknąć dodawania odwołania do System.Webzestawu.

Billy Jo
źródło
1
Uri.EscapeUriString () nie zrobiło nic dla mnie, ale udało mi się poprawnie zakodować ciągi znaków przy użyciu adresu URL za pomocą Uri.EscapeDataString ()
Toland Hon
3
@TolandHon: Rzeczywiście. Powodem jest to, że Uri.EscapeUriString()odpowiada to JavaScriptowi encodeURI()- który zachowuje znaki zarezerwowane dla URI. takie jak /,, &... as-is (plus #), podczas gdy - jak odkryłeś, jest Uri.EscapeDataString()to odpowiednik JavaScript encodeURIComponent().
mklement0
9

W przypadku aplikacji ze Sklepu Windows nie będziesz mieć HttpUtility. Zamiast tego masz:

W przypadku identyfikatora URI przed „?”:

  • System. Uri.EscapeUriString („example.com/Stack Overflow ++?”)
    • -> „example.com/Stack%20Overflow++?”

W przypadku nazwy lub wartości zapytania URI po znaku „?”:

  • System. Uri.EscapeDataString ("Stack Overflow ++")
    • -> "Stack% 20Overflow% 2B% 2B"

W przypadku nazwy lub wartości zapytania x-www-form-urlencoded w treści POST:

  • System.Net. WebUtility.UrlEncode ("Przepełnienie stosu ++")
    • -> "Stos + przepełnienie% 2B% 2B"
Cœur
źródło
6

Możesz użyć obiektu Server w przestrzeni nazw System.Web

Server.UrlEncode, Server.UrlDecode, Server.HtmlEncode i Server.HtmlDecode.

Edycja: poster dodał, że jest to aplikacja Windows, a nie internetowa, jak można by sądzić. Elementy wymienione powyżej byłyby dostępne z klasy HttpUtility wewnątrz System.Web, którą należy dodać jako odniesienie do projektu.

Mitchel Sellers
źródło
1
Obiekt serwera jest niedostępny z aplikacji systemu Windows
travis