Codifica URL usando C #


340

Ho un'applicazione che invia una richiesta POST al software del forum VB e accede qualcuno (senza impostare cookie o altro).

Una volta che l'utente ha effettuato l'accesso, creo una variabile che crea un percorso sul proprio computer locale.

c: \ TempFolder \ Data \ nomeutente

Il problema è che alcuni nomi utente stanno generando un'eccezione "Caratteri illegali". Ad esempio, se il mio nome utente fosse mas|fenix, genererebbe un'eccezione.

Path.Combine( _      
  Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData), _
  DateTime.Now.ToString("ddMMyyhhmm") + "-" + form1.username)

Non voglio rimuoverlo dalla stringa, ma una cartella con il loro nome utente viene creata tramite FTP su un server. E questo porta alla mia seconda domanda. Se sto creando una cartella sul server, posso lasciare i "caratteri illegali" in? Lo chiedo solo perché il server è basato su Linux e non sono sicuro che Linux lo accetti o meno.

EDIT: Sembra che la codifica URL NON sia ciò che voglio .. Ecco cosa voglio fare:

old username = mas|fenix
new username = mas%xxfenix

Dove% xx è il valore ASCII o qualsiasi altro valore che identificherebbe facilmente il carattere.


Incorporare questo per rendere sicuri i nomi delle cartelle del file system: http://stackoverflow.com/questions/333175/is-there-a-way-of-making-strings-file-path-safe-in-c
missaghi

Risposte:


191

Modifica: nota che questa risposta non è più aggiornata. Vedi la risposta di Siarhei Kuchuk di seguito per una soluzione migliore

UrlEncoding farà ciò che stai suggerendo qui. Con C #, usi semplicemente HttpUtility, come detto.

Puoi anche Regex i caratteri illegali e poi sostituirli, ma questo diventa molto più complesso, in quanto dovrai avere una qualche forma di macchina a stati (switch ... case, per esempio) per sostituire con i caratteri corretti. Dal momento che lo UrlEncodefa in anticipo, è piuttosto facile.

Per quanto riguarda Linux contro Windows, ci sono alcuni caratteri accettabili in Linux che non sono in Windows, ma non mi preoccuperei di ciò, poiché il nome della cartella può essere restituito decodificando la stringa Url, utilizzando UrlDecode, in modo da poter round trip il i cambiamenti.


5
questa risposta non è più aggiornata ora. leggi alcune risposte di seguito - a partire da .net45 questa potrebbe essere la soluzione corretta: msdn.microsoft.com/en-us/library/…
blueberryfields

1
Per FTP ogni parte Uri (nome cartella o file) può essere costruita usando Uri.EscapeDataString (fileOrFolderName) consentendo tutti i caratteri non Uri compatibili (spazi, unicode ...). Ad esempio, per consentire qualsiasi carattere nel nome file, utilizzare: req = (FtpWebRequest) WebRequest.Create (nuovo Uri (percorso + "/" + Uri.EscapeDataString (nome file))); Utilizzando HttpUtility.UrlEncode () sostituire gli spazi con segni più (+). Un comportamento corretto per i motori di ricerca ma errato per i nomi di file / cartelle.
Renaud Bancel,

asp.net blocca la maggior parte di xss in url quando ricevi un avviso ogni volta che provi ad aggiungere js script A potentially dangerous Request.Path value was detected from the client.
Apprendimento del

511

Ho sperimentato i vari metodi forniti da .NET per la codifica degli URL. Forse la seguente tabella sarà utile (come output di un'app di test che ho scritto):

Unencoded UrlEncoded UrlEncodedUnicode UrlPathEncoded EscapedDataString EscapedUriString HtmlEncoded HtmlAttributeEncoded HexEscaped
A         A          A                 A              A                 A                A           A                    %41
B         B          B                 B              B                 B                B           B                    %42

a         a          a                 a              a                 a                a           a                    %61
b         b          b                 b              b                 b                b           b                    %62

0         0          0                 0              0                 0                0           0                    %30
1         1          1                 1              1                 1                1           1                    %31

[space]   +          +                 %20            %20               %20              [space]     [space]              %20
!         !          !                 !              !                 !                !           !                    %21
"         %22        %22               "              %22               %22              "      "               %22
#         %23        %23               #              %23               #                #           #                    %23
$         %24        %24               $              %24               $                $           $                    %24
%         %25        %25               %              %25               %25              %           %                    %25
&         %26        %26               &              %26               &                &       &                %26
'         %27        %27               '              '                 '                '       '                %27
(         (          (                 (              (                 (                (           (                    %28
)         )          )                 )              )                 )                )           )                    %29
*         *          *                 *              %2A               *                *           *                    %2A
+         %2b        %2b               +              %2B               +                +           +                    %2B
,         %2c        %2c               ,              %2C               ,                ,           ,                    %2C
-         -          -                 -              -                 -                -           -                    %2D
.         .          .                 .              .                 .                .           .                    %2E
/         %2f        %2f               /              %2F               /                /           /                    %2F
:         %3a        %3a               :              %3A               :                :           :                    %3A
;         %3b        %3b               ;              %3B               ;                ;           ;                    %3B
<         %3c        %3c               <              %3C               %3C              &lt;        &lt;                 %3C
=         %3d        %3d               =              %3D               =                =           =                    %3D
>         %3e        %3e               >              %3E               %3E              &gt;        >                    %3E
?         %3f        %3f               ?              %3F               ?                ?           ?                    %3F
@         %40        %40               @              %40               @                @           @                    %40
[         %5b        %5b               [              %5B               %5B              [           [                    %5B
\         %5c        %5c               \              %5C               %5C              \           \                    %5C
]         %5d        %5d               ]              %5D               %5D              ]           ]                    %5D
^         %5e        %5e               ^              %5E               %5E              ^           ^                    %5E
_         _          _                 _              _                 _                _           _                    %5F
`         %60        %60               `              %60               %60              `           `                    %60
{         %7b        %7b               {              %7B               %7B              {           {                    %7B
|         %7c        %7c               |              %7C               %7C              |           |                    %7C
}         %7d        %7d               }              %7D               %7D              }           }                    %7D
~         %7e        %7e               ~              ~                 ~                ~           ~                    %7E

Ā         %c4%80     %u0100            %c4%80         %C4%80            %C4%80           Ā           Ā                    [OoR]
ā         %c4%81     %u0101            %c4%81         %C4%81            %C4%81           ā           ā                    [OoR]
Ē         %c4%92     %u0112            %c4%92         %C4%92            %C4%92           Ē           Ē                    [OoR]
ē         %c4%93     %u0113            %c4%93         %C4%93            %C4%93           ē           ē                    [OoR]
Ī         %c4%aa     %u012a            %c4%aa         %C4%AA            %C4%AA           Ī           Ī                    [OoR]
ī         %c4%ab     %u012b            %c4%ab         %C4%AB            %C4%AB           ī           ī                    [OoR]
Ō         %c5%8c     %u014c            %c5%8c         %C5%8C            %C5%8C           Ō           Ō                    [OoR]
ō         %c5%8d     %u014d            %c5%8d         %C5%8D            %C5%8D           ō           ō                    [OoR]
Ū         %c5%aa     %u016a            %c5%aa         %C5%AA            %C5%AA           Ū           Ū                    [OoR]
ū         %c5%ab     %u016b            %c5%ab         %C5%AB            %C5%AB           ū           ū                    [OoR]

Le colonne rappresentano le codifiche come segue:

  • urlencoded: HttpUtility.UrlEncode

  • UrlEncodedUnicode: HttpUtility.UrlEncodeUnicode

  • UrlPathEncoded: HttpUtility.UrlPathEncode

  • EscapedDataString: Uri.EscapeDataString

  • EscapedUriString: Uri.EscapeUriString

  • HtmlEncoded: HttpUtility.HtmlEncode

  • HtmlAttributeEncoded: HttpUtility.HtmlAttributeEncode

  • HexEscaped: Uri.HexEscape

APPUNTI:

  1. HexEscapepuò gestire solo i primi 255 caratteri. Pertanto genera ArgumentOutOfRangeun'eccezione per i caratteri latini A-estesi (ad es. Â).

  2. Questa tabella è stata generata in .NET 4.0 (vedi il commento di Levi Botelho che dice che la codifica in .NET 4.5 è leggermente diversa).

MODIFICARE:

Ho aggiunto una seconda tabella con le codifiche per .NET 4.5. Vedi questa risposta: https://stackoverflow.com/a/21771206/216440

MODIFICA 2:

Dato che le persone sembrano apprezzare questi tavoli, ho pensato che potrebbe piacerti il ​​codice sorgente che genera il tavolo, così puoi giocare da solo. È una semplice applicazione console C #, che può essere indirizzata a .NET 4.0 o 4.5:

using System;
using System.Collections.Generic;
using System.Text;
// Need to add a Reference to the System.Web assembly.
using System.Web;

namespace UriEncodingDEMO2
{
    class Program
    {
        static void Main(string[] args)
        {
            EncodeStrings();

            Console.WriteLine();
            Console.WriteLine("Press any key to continue...");
            Console.Read();
        }

        public static void EncodeStrings()
        {
            string stringToEncode = "ABCD" + "abcd"
            + "0123" + " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" + "ĀāĒēĪīŌōŪū";

            // Need to set the console encoding to display non-ASCII characters correctly (eg the 
            //  Latin A-Extended characters such as ĀāĒē...).
            Console.OutputEncoding = Encoding.UTF8;

            // Will also need to set the console font (in the console Properties dialog) to a font 
            //  that displays the extended character set correctly.
            // The following fonts all display the extended characters correctly:
            //  Consolas
            //  DejaVu Sana Mono
            //  Lucida Console

            // Also, in the console Properties, set the Screen Buffer Size and the Window Size 
            //  Width properties to at least 140 characters, to display the full width of the 
            //  table that is generated.

            Dictionary<string, Func<string, string>> columnDetails =
                new Dictionary<string, Func<string, string>>();
            columnDetails.Add("Unencoded", (unencodedString => unencodedString));
            columnDetails.Add("UrlEncoded",
                (unencodedString => HttpUtility.UrlEncode(unencodedString)));
            columnDetails.Add("UrlEncodedUnicode",
                (unencodedString => HttpUtility.UrlEncodeUnicode(unencodedString)));
            columnDetails.Add("UrlPathEncoded",
                (unencodedString => HttpUtility.UrlPathEncode(unencodedString)));
            columnDetails.Add("EscapedDataString",
                (unencodedString => Uri.EscapeDataString(unencodedString)));
            columnDetails.Add("EscapedUriString",
                (unencodedString => Uri.EscapeUriString(unencodedString)));
            columnDetails.Add("HtmlEncoded",
                (unencodedString => HttpUtility.HtmlEncode(unencodedString)));
            columnDetails.Add("HtmlAttributeEncoded",
                (unencodedString => HttpUtility.HtmlAttributeEncode(unencodedString)));
            columnDetails.Add("HexEscaped",
                (unencodedString
                    =>
                    {
                        // Uri.HexEscape can only handle the first 255 characters so for the 
                        //  Latin A-Extended characters, such as A, it will throw an 
                        //  ArgumentOutOfRange exception.                       
                        try
                        {
                            return Uri.HexEscape(unencodedString.ToCharArray()[0]);
                        }
                        catch
                        {
                            return "[OoR]";
                        }
                    }));

            char[] charactersToEncode = stringToEncode.ToCharArray();
            string[] stringCharactersToEncode = Array.ConvertAll<char, string>(charactersToEncode,
                (character => character.ToString()));
            DisplayCharacterTable<string>(stringCharactersToEncode, columnDetails);
        }

        private static void DisplayCharacterTable<TUnencoded>(TUnencoded[] unencodedArray,
            Dictionary<string, Func<TUnencoded, string>> mappings)
        {
            foreach (string key in mappings.Keys)
            {
                Console.Write(key.Replace(" ", "[space]") + " ");
            }
            Console.WriteLine();

            foreach (TUnencoded unencodedObject in unencodedArray)
            {
                string stringCharToEncode = unencodedObject.ToString();
                foreach (string columnHeader in mappings.Keys)
                {
                    int columnWidth = columnHeader.Length + 1;
                    Func<TUnencoded, string> encoder = mappings[columnHeader];
                    string encodedString = encoder(unencodedObject);

                    // ASSUMPTION: Column header will always be wider than encoded string.
                    Console.Write(encodedString.Replace(" ", "[space]").PadRight(columnWidth));
                }
                Console.WriteLine();
            }
        }
    }
}

2
Questa è una risposta fantastica Ho scoperto che volevo usare Uri.EscapeDataString e non includere System.Web. Grazie per questo tavolo.
Seravy,

7
Si noti che questo non è più preciso al 100%. Alcune funzioni sono leggermente cambiate tra .NET 4 e .NET 4.5. Vedi stackoverflow.com/q/20003106/1068266 .
Levi Botelho

2
@Levi: grazie per il testa a testa. Ho aggiunto una seconda risposta con la tabella per .NET 4.5. Ho modificato la risposta originale per collegarmi alla seconda tabella.
Simon Tewsi,

Si noti che la documentazione .NET dice Non utilizzare; destinato esclusivamente alla compatibilità del browser. Usa UrlEncode. , ma quel metodo codifica molti altri caratteri indesiderati. Il più vicino è Uri.EscapeUriString, ma attenzione che non supporta un nullargomento.
Andrew

1
Ho dimenticato di menzionare, il mio commento sopra è per UrlPathEncode. Quindi, in sostanza, sostituire UrlPathEncodecon Uri.EscapeUriString.
Andrew

279

Dovresti codificare solo il nome utente o altra parte dell'URL che potrebbe non essere valido. L'URL che codifica un URL può causare problemi poiché qualcosa del genere:

string url = HttpUtility.UrlEncode("http://www.google.com/search?q=Example");

Cederà

http% 3A% 2F% 2fwww.google.com% 2fsearch% 3fq% 3dExample

Questo ovviamente non funzionerà bene. Invece, dovresti codificare SOLO il valore della coppia chiave / valore nella stringa di query, in questo modo:

string url = "http://www.google.com/search?q=" + HttpUtility.UrlEncode("Example");

Spero che questo aiuti. Inoltre, come accennato in precedenza, dovrai comunque assicurarti che i caratteri del nome file illegali vengano rimossi, altrimenti il ​​file system non gradirà il percorso.


34
L'uso del metodo HttpUtility.UrlPathEncode dovrebbe prevenire il problema che stai descrivendo qui.
vipirtti,

12
@DJ Pirtu: È vero che UrlPathEncode non apporterà tali modifiche indesiderate nel percorso, tuttavia non codificherà nulla dopo il ?(poiché presuppone che la stringa di query sia già codificata). Nell'esempio di Dan Herbert sembra che Examplestia fingendo che il testo richieda la codifica, quindi HttpUtility.UrlPathEncode("http://www.google.com/search?q=Example");non funzionerà. Provalo con ?q=Ex&ple(dove si trova il risultato desiderato ?q=Ex%26ple). Non funzionerà perché (1) UrlPathEncode non tocca nulla dopo ?, e (2) UrlPathEncode non codifica &comunque.
Tim Goodman,

1
Vedi qui: connect.microsoft.com/VisualStudio/feedback/details/551839/… Dovrei aggiungere che ovviamente è bene che UrlPathEncode non codifichi &, perché è necessario per delimitare i parametri della stringa di query. Ma ci sono volte in cui vuoi anche e commerciali codificate.
Tim Goodman,

10
HttpUtility è riuscito da WebUtility nelle ultime versioni, risparmiando un po 'di tempo :)
Wiseman,

190

Il modo migliore è usare

Uri.EscapeUriString

per non fare riferimento al profilo completo di .net 4.


1
Totalmente d'accordo poiché spesso il "Profilo client" è sufficiente per le app che utilizzano System.Net ma non utilizzano System.Web ;-)
hfrmobile

6
OP sta parlando di verificarne la compatibilità con il file system, quindi non funzionerà. Il set di caratteri non consentiti di Windows è '["/", "\\", "<", ">", ":", "\" "," | ","? "," * "]' Ma molti di questi non essere codificato usando EscapedUriString (vedi tabella sotto - grazie per quella tabella @Simon Tewsi) ... "crea un percorso sul loro computer locale" -OP UrlEncoded si occupa di quasi tutti i problemi, ma non risolve il problema problema con "%" o "% 3f" nell'input originale, dato che un "decodifica" ora sarà diverso dall'originale.
m1m1k

6
solo per chiarire: QUESTA risposta NON FUNZIONA per i file system
m1m1k

1
Inoltre, a partire da .NET Framework 4.5, il profilo client è stato sospeso e solo il pacchetto ridistribuibile completo è disponibile.
dal

29
stackoverflow.com/a/34189188/3436164 Usa Uri.EscapeDataStringNOT Uri.EscapeUriStringLeggi questo commento, mi ha aiutato.
Ykadaru,

181

Da .NET Framework 4.5 e .NET Standard 1.0 dovresti usare WebUtility.UrlEncode. Vantaggi rispetto alle alternative:

  1. Fa parte di .NET Framework 4.5+, .NET Core 1.0+, .NET Standard 1.0+, UWP 10.0+ e tutte le piattaforme Xamarin. HttpUtility, pur essendo disponibile in .NET Framework in precedenza (.NET Framework 1.1+), diventa disponibile su altre piattaforme molto più tardi (.NET Core 2.0+, .NET Standard 2.0+) e non è ancora disponibile in UWP (vedere la domanda correlata ).

  2. In .NET Framework, risiede inSystem.dll , quindi non richiede alcun riferimento aggiuntivo, a differenza HttpUtility.

  3. Si sfugge correttamente i caratteri per gli URL , a differenza Uri.EscapeUriString(vedi commenti alla risposta di drweb86 ).

  4. Non ha limiti sulla lunghezza della stringa , a differenza di Uri.EscapeDataString(vedi domanda correlata ), quindi può essere utilizzato per richieste POST, ad esempio.


Mi piace il modo in cui codifica usando "+" invece di% 20 per gli spazi .. ma questo non rimuove ancora "dall'URL e mi dà un URL non valido ... vabbè .. dovrò semplicemente fare un rimpiazzo (" "" "", "")
Piotr Kula,

85

Levi Botelho ha commentato che la tabella delle codifiche precedentemente generata non è più accurata per .NET 4.5, poiché le codifiche sono leggermente cambiate tra .NET 4.0 e 4.5. Quindi ho rigenerato la tabella per .NET 4.5:

Unencoded UrlEncoded UrlEncodedUnicode UrlPathEncoded WebUtilityUrlEncoded EscapedDataString EscapedUriString HtmlEncoded HtmlAttributeEncoded WebUtilityHtmlEncoded HexEscaped
A         A          A                 A              A                    A                 A                A           A                    A                     %41
B         B          B                 B              B                    B                 B                B           B                    B                     %42

a         a          a                 a              a                    a                 a                a           a                    a                     %61
b         b          b                 b              b                    b                 b                b           b                    b                     %62

0         0          0                 0              0                    0                 0                0           0                    0                     %30
1         1          1                 1              1                    1                 1                1           1                    1                     %31

[space]   +          +                 %20            +                    %20               %20              [space]     [space]              [space]               %20
!         !          !                 !              !                    %21               !                !           !                    !                     %21
"         %22        %22               "              %22                  %22               %22              &quot;      &quot;               &quot;                %22
#         %23        %23               #              %23                  %23               #                #           #                    #                     %23
$         %24        %24               $              %24                  %24               $                $           $                    $                     %24
%         %25        %25               %              %25                  %25               %25              %           %                    %                     %25
&         %26        %26               &              %26                  %26               &                &amp;       &amp;                &amp;                 %26
'         %27        %27               '              %27                  %27               '                &#39;       &#39;                &#39;                 %27
(         (          (                 (              (                    %28               (                (           (                    (                     %28
)         )          )                 )              )                    %29               )                )           )                    )                     %29
*         *          *                 *              *                    %2A               *                *           *                    *                     %2A
+         %2b        %2b               +              %2B                  %2B               +                +           +                    +                     %2B
,         %2c        %2c               ,              %2C                  %2C               ,                ,           ,                    ,                     %2C
-         -          -                 -              -                    -                 -                -           -                    -                     %2D
.         .          .                 .              .                    .                 .                .           .                    .                     %2E
/         %2f        %2f               /              %2F                  %2F               /                /           /                    /                     %2F
:         %3a        %3a               :              %3A                  %3A               :                :           :                    :                     %3A
;         %3b        %3b               ;              %3B                  %3B               ;                ;           ;                    ;                     %3B
<         %3c        %3c               <              %3C                  %3C               %3C              &lt;        &lt;                 &lt;                  %3C
=         %3d        %3d               =              %3D                  %3D               =                =           =                    =                     %3D
>         %3e        %3e               >              %3E                  %3E               %3E              &gt;        >                    &gt;                  %3E
?         %3f        %3f               ?              %3F                  %3F               ?                ?           ?                    ?                     %3F
@         %40        %40               @              %40                  %40               @                @           @                    @                     %40
[         %5b        %5b               [              %5B                  %5B               [                [           [                    [                     %5B
\         %5c        %5c               \              %5C                  %5C               %5C              \           \                    \                     %5C
]         %5d        %5d               ]              %5D                  %5D               ]                ]           ]                    ]                     %5D
^         %5e        %5e               ^              %5E                  %5E               %5E              ^           ^                    ^                     %5E
_         _          _                 _              _                    _                 _                _           _                    _                     %5F
`         %60        %60               `              %60                  %60               %60              `           `                    `                     %60
{         %7b        %7b               {              %7B                  %7B               %7B              {           {                    {                     %7B
|         %7c        %7c               |              %7C                  %7C               %7C              |           |                    |                     %7C
}         %7d        %7d               }              %7D                  %7D               %7D              }           }                    }                     %7D
~         %7e        %7e               ~              %7E                  ~                 ~                ~           ~                    ~                     %7E

Ā         %c4%80     %u0100            %c4%80         %C4%80               %C4%80            %C4%80           Ā           Ā                    Ā                     [OoR]
ā         %c4%81     %u0101            %c4%81         %C4%81               %C4%81            %C4%81           ā           ā                    ā                     [OoR]
Ē         %c4%92     %u0112            %c4%92         %C4%92               %C4%92            %C4%92           Ē           Ē                    Ē                     [OoR]
ē         %c4%93     %u0113            %c4%93         %C4%93               %C4%93            %C4%93           ē           ē                    ē                     [OoR]
Ī         %c4%aa     %u012a            %c4%aa         %C4%AA               %C4%AA            %C4%AA           Ī           Ī                    Ī                     [OoR]
ī         %c4%ab     %u012b            %c4%ab         %C4%AB               %C4%AB            %C4%AB           ī           ī                    ī                     [OoR]
Ō         %c5%8c     %u014c            %c5%8c         %C5%8C               %C5%8C            %C5%8C           Ō           Ō                    Ō                     [OoR]
ō         %c5%8d     %u014d            %c5%8d         %C5%8D               %C5%8D            %C5%8D           ō           ō                    ō                     [OoR]
Ū         %c5%aa     %u016a            %c5%aa         %C5%AA               %C5%AA            %C5%AA           Ū           Ū                    Ū                     [OoR]
ū         %c5%ab     %u016b            %c5%ab         %C5%AB               %C5%AB            %C5%AB           ū           ū                    ū                     [OoR]

Le colonne rappresentano le codifiche come segue:

  • urlencoded: HttpUtility.UrlEncode
  • UrlEncodedUnicode: HttpUtility.UrlEncodeUnicode
  • UrlPathEncoded: HttpUtility.UrlPathEncode
  • WebUtilityUrlEncoded: WebUtility.UrlEncode
  • EscapedDataString: Uri.EscapeDataString
  • EscapedUriString: Uri.EscapeUriString
  • HtmlEncoded: HttpUtility.HtmlEncode
  • HtmlAttributeEncoded: HttpUtility.HtmlAttributeEncode
  • WebUtilityHtmlEncoded: WebUtility.HtmlEncode
  • HexEscaped: Uri.HexEscape

APPUNTI:

  1. HexEscape può gestire solo i primi 255 caratteri. Pertanto genera un'eccezione ArgumentOutOfRange per i caratteri latini A-estesi (ad esempio Â).

  2. Questa tabella è stata generata in .NET 4.5 (consultare la risposta https://stackoverflow.com/a/11236038/216440 per le codifiche relative a .NET 4.0 e versioni successive).

MODIFICARE:

  1. Come risultato della risposta di Discord ho aggiunto i nuovi metodi WebUtility UrlEncode e HtmlEncode, che sono stati introdotti in .NET 4.5.

2
No non UrlPathEncode dell'utente - anche MSDN dice che non deve essere usato. È stato creato per risolvere un problema con netscape 2 msdn.microsoft.com/en-us/library/…
Jeff

Server.URLEncode è un'altra variante su questo tema? Genera un output diverso?
ALEXintlsos,

2
@ALEX: in ASP.NET l'oggetto Server è un'istanza di HttpServerUtility. Usando il decompilatore dotPeek ho dato un'occhiata a HttpServerUtility.UrlEncode. Chiama solo HttpUtility.UrlEncode in modo che l'output dei due metodi sia identico.
Simon Tewsi,

Sembra che, anche con questa sovrabbondanza di metodi di codifica, tutti falliscono in modo abbastanza spettacolare per qualsiasi cosa al di sopra di Latin-1, come → o ☠. (UrlEncodedUnicode sembra come se almeno tentasse di supportare Unicode, ma è deprecato / mancante.)
brianary

Simone, puoi semplicemente integrare questa risposta nella risposta accettata? sarà bello averlo in una risposta. potresti integrarlo e creare un'intestazione h1 nella parte inferiore di quella risposta, oppure integrarlo in una tabella e contrassegnare diverse linee, come: (Net4.0) ? %3f................................ (Net4.5) ? %3f ..................................
T.Todua,

60

La codifica URL è facile in .NET. Uso:

System.Web.HttpUtility.UrlEncode(string url)

Se verrà decodificato per ottenere il nome della cartella, dovrai comunque escludere i caratteri che non possono essere utilizzati nei nomi delle cartelle (*,?, /, Ecc.)


Codifica ogni personaggio che non fa parte dell'alfabeto?
masfenix,

1
La codifica URL converte i caratteri non consentiti in un URL in equivalenti entità carattere. Elenco di caratteri non sicuri: blooberry.com/indexdot/html/topics/urlencoding.htm
Ian Robinson,

MSDN collegamento on HttpUtility.UrlEncode: msdn.microsoft.com/en-us/library/4fkewx0t.aspx
Ian Robinson

11
È buona norma inserire l'intero System.Web ... parte della tua risposta, fa risparmiare un sacco di tempo a qualcuno :) grazie
Liam

3
Questo è pericoloso: non tutti i caratteri dell'url devono essere codificati, ma solo i valori dei parametri di querystring. Il modo in cui suggerisci codificherà anche il simbolo & necessario per creare più parametri nella stringa di query. La soluzione è di codificare ogni valore dei parametri se necessario
Marco Staffoli,

12

Se non riesci a vedere System.Web, modifica le impostazioni del progetto. Il framework di destinazione dovrebbe essere ".NET Framework 4" anziché "Profilo client .NET Framework 4"


1
A mio avviso, gli sviluppatori dovrebbero conoscere "Profili .NET" e dovrebbero usare quello corretto per i loro scopi! Basta aggiungere il profilo completo per ottenere (ad esempio System.Web) senza sapere davvero perché aggiungono il profilo completo, non è molto intelligente. Utilizzare "Profilo client" per le app client e il profilo completo solo quando necessario (ad es. Un client WinForms o WPF deve utilizzare il profilo client e non il profilo completo)! ad es. non vedo alcun motivo utilizzando HttpServerUtility in un'app client ^^ ... se necessario, c'è qualcosa di sbagliato nel design dell'app!
hfrmobile,

4
Veramente? Non vedi mai la necessità che un'app client costruisca un URL? Cosa fai per vivere - doveri di sorveglianza?
sproketboy,

@hfrmobile: no. È tutto sbagliato nel modello di profilo (che ha vissuto solo una volta ed è stato abbandonato nella prossima versione). Ed era ovvio sin dall'inizio. È ovvio per te adesso? Pensa prima, non accettare tutto "così com'è" ciò che msft cerca di venderti; P
abatishchev,

Siamo spiacenti, ma non ho mai detto che un client non deve mai creare / utilizzare un URL. Finché .NET 4.0 è in uso, l'utente dovrebbe preoccuparsene. Per farla breve: gli sviluppatori dovrebbero pensarci due volte prima di aggiungere HttpServerUtility a un client. Ci sono altri / modi migliori, basta vedere la risposta con 139 voti o "Dal momento che .NET Framework 4.5 è possibile utilizzare WebUtility.UrlEncode. Innanzitutto, risiede in System.dll, quindi non richiede alcun riferimento aggiuntivo.".
hfrmobile,

9

L'implementazione di .NET UrlEncodenon è conforme a RFC 3986.

  1. Alcuni personaggi non sono codificati ma dovrebbero esserlo. I !()*caratteri sono elencati nella sezione 2.2 di RFC come caratteri riservati che devono essere codificati ma .NET non riesce a codificare questi caratteri.

  2. Alcuni personaggi sono codificati ma non dovrebbero esserlo. I .-_caratteri non sono elencati nella sezione 2.2 della RFC come carattere riservato che non dovrebbe essere codificato, ma .NET codifica erroneamente questi caratteri.

  3. La RFC specifica che, per essere coerenti, le implementazioni dovrebbero usare HEXDIG maiuscolo, dove .NET produce HEXDIG minuscolo.


4

Penso che le persone qui siano state distratte dal messaggio UrlEncode. URLEncoding non è quello che vuoi - vuoi codificare cose che non funzioneranno come un nome di file sul sistema di destinazione.

Supponendo che tu voglia un po 'di generalità - sentiti libero di trovare i personaggi illegali su diversi sistemi (MacOS, Windows, Linux e Unix), uniscili per formare una serie di personaggi per fuggire.

Per quanto riguarda la fuga, un HexEscape dovrebbe andare bene (Sostituendo i caratteri con% XX). Converti ogni carattere in byte UTF-8 e codifica tutto> 128 se vuoi supportare sistemi che non fanno unicode. Ma ci sono altri modi, come usare le barre rovesciate "\" o la codifica HTML "" ". Puoi crearne uno tuo. Tutto ciò che un sistema deve fare è" codificare "il carattere incompatibile. I sistemi sopra ti permettono di ricreare il nome originale - ma funziona anche qualcosa come sostituire i caratteri cattivi con spazi.

Sulla stessa tangente di cui sopra, l'unico da usare è

Uri.EscapeDataString

- Codifica tutto ciò che è necessario per OAuth, non codifica le cose che OAuth proibisce la codifica e codifica lo spazio come% 20 e non + (anche nelle specifiche OATH) Vedi: RFC 3986. AFAIK, questo è il le ultime specifiche URI.


3

Ho scritto un metodo C # che codifica URL TUTTI i simboli:

    /// <summary>
    /// !#$345Hf} → %21%23%24%33%34%35%48%66%7D
    /// </summary>
    public static string UrlEncodeExtended( string value )
    {
        char[] chars = value.ToCharArray();
        StringBuilder encodedValue = new StringBuilder();
        foreach (char c in chars)
        {
            encodedValue.Append( "%" + ( (int)c ).ToString( "X2" ) );
        }
        return encodedValue.ToString();
    }

1

Idealmente questi dovrebbero andare in una classe chiamata "FileNaming" o forse rinominare Encode in "FileNameEncode". Nota: questi non sono progettati per gestire percorsi completi, ma solo i nomi di cartelle e / o file. Idealmente, dovresti prima dividere ("/") il tuo percorso completo e poi controllare i pezzi. E ovviamente invece di un sindacato, potresti semplicemente aggiungere il carattere "%" all'elenco dei caratteri non consentiti in Windows, ma penso che sia più utile / leggibile / fattuale in questo modo. Decode () è esattamente lo stesso, ma cambia "Sostituisci" (Uri.HexEscape (s [0]), s) con il carattere.

public static List<string> urlEncodedCharacters = new List<string>
{
  "/", "\\", "<", ">", ":", "\"", "|", "?", "%" //and others, but not *
};
//Since this is a superset of urlEncodedCharacters, we won't be able to only use UrlEncode() - instead we'll use HexEncode
public static List<string> specialCharactersNotAllowedInWindows = new List<string>
{
  "/", "\\", "<", ">", ":", "\"", "|", "?", "*" //windows dissallowed character set
};

    public static string Encode(string fileName)
    {
        //CheckForFullPath(fileName); // optional: make sure it's not a path?
        List<string> charactersToChange = new List<string>(specialCharactersNotAllowedInWindows);
        charactersToChange.AddRange(urlEncodedCharacters.
            Where(x => !urlEncodedCharacters.Union(specialCharactersNotAllowedInWindows).Contains(x)));   // add any non duplicates (%)

        charactersToChange.ForEach(s => fileName = fileName.Replace(s, Uri.HexEscape(s[0])));   // "?" => "%3f"

        return fileName;
    }

Grazie @ simon-tewsi per l'utilissima tabella sopra!


utile anche: Path.GetInvalidFileNameChars()
m1m1k

sì. Ecco un modo per farlo: foreach (char c in System.IO.Path.GetInvalidFileNameChars ()) {filename = filename.Replace (c, '_'); }
Netfed

0

Oltre alla risposta di @Dan Herbert, dovresti codificare solo i valori in generale.

Split ha il parametro params Split ('&', '='); espressione divisa per prima e poi '=', quindi gli elementi dispari sono tutti i valori da codificare mostrati di seguito.

public static void EncodeQueryString(ref string queryString)
{
    var array=queryString.Split('&','=');
    for (int i = 0; i < array.Length; i++) {
        string part=array[i];
        if(i%2==1)
        {               
            part=System.Web.HttpUtility.UrlEncode(array[i]);
            queryString=queryString.Replace(array[i],part);
        }
    }
}
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.