C#을 사용한 URL 인코딩
저는 VB 포럼 소프트웨어에 POST 요청을 전송하고 쿠키 등을 설정하지 않고 누군가를 로그인하는 애플리케이션을 가지고 있습니다.
사용자가 로그인하면 로컬 컴퓨터에 경로를 생성하는 변수를 만듭니다.
c:\folder\date\details
문제는 일부 사용자 이름이 '불법 문자' 예외를 던지고 있다는 점입니다.예를 들어 내 사용자 이름이mas|fenix그것은 예외가 될 것입니다.
Path.Combine( _
Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData), _
DateTime.Now.ToString("ddMMyyhhmm") + "-" + form1.username)
문자열에서 제거하고 싶지 않지만 사용자 이름을 가진 폴더가 FTP를 통해 서버에 생성됩니다.그리고 이것은 제 두번째 질문으로 이어집니다.서버에 폴더를 작성하는 경우 "잘못된 문자"를 그대로 둘 수 있습니까?서버가 리눅스 기반이기 때문에 이것만 묻고, 리눅스가 수락하는지 아닌지는 잘 모르겠습니다.
편집: URL 인코딩이 제가 원하는 것이 아닌 것 같습니다.제가 하고 싶은 일은 다음과 같습니다.
old username = mas|fenix
new username = mas%xxfenix
여기서 %xx는 ASCII 값 또는 문자를 쉽게 식별할 수 있는 기타 값입니다.
저는 다양한 방법을 실험해 왔습니다.NET은 URL 인코딩을 제공합니다.아마 다음 표가 유용할 것입니다(제가 작성한 테스트 앱의 출력).
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 < < %3C
= %3d %3d = %3D = = = %3D
> %3e %3e > %3E %3E > > %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]
열은 다음과 같이 인코딩을 나타냅니다.
인딩된 URL:
HttpUtility.UrlEncodeURL 인코딩유니코드:
HttpUtility.UrlEncodeUnicodeUrlPathEncoded:
HttpUtility.UrlPathEncode이스케이프된 데이터 문자열:
Uri.EscapeDataStringUriString: UriString:
Uri.EscapeUriStringHtml 인코딩:
HttpUtility.HtmlEncodeHtml 특성 인코딩:
HttpUtility.HtmlAttributeEncode16진수 이스케이프:
Uri.HexEscape
주의:
HexEscape에서는 처음 255자만 처리할 수 있습니다.그러므로 그것은 그것을 던집니다.ArgumentOutOfRange예외는 라틴어 A-확장 문자(예: āA)입니다.이 테이블은 에서 생성되었습니다.NET 4.0 (아래의 Levi Botelho의 주석 참조)에 인코딩이 나와 있습니다.NET 4.5는 약간 다릅니다.
편집:
인코딩이 포함된 두 번째 테이블을 추가했습니다.NET 4.5.다음 답변을 참조하십시오. https://stackoverflow.com/a/21771206/216440
편집 2:
사람들이 이 테이블을 좋아하는 것처럼 보이기 때문에, 저는 당신이 테이블을 생성하는 소스 코드를 좋아할 것이라고 생각했습니다. 그래서 당신은 당신 자신을 가지고 놀 수 있습니다.이것은 간단한 C# 콘솔 응용 프로그램으로, 둘 중 하나를 대상으로 할 수 있습니다.NET 4.0 또는 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();
}
}
}
}
dotnetfiddle.net 에서 코드를 실행하려면 여기를 클릭하십시오.
사용자 이름 또는 URL의 다른 부분만 인코딩해야 합니다.URL을 인코딩하는 URL은 다음과 같은 문제를 일으킬 수 있습니다.
string url = HttpUtility.UrlEncode("http://www.google.com/search?q=Example");
윌 항복
http%3a%2f%2fwww.google.com %2fsearch%3fq%3d예
이것은 분명히 잘 작동하지 않을 것입니다.대신 다음과 같이 쿼리 문자열에서 키/값 쌍의 값만 인코딩해야 합니다.
string url = "http://www.google.com/search?q=" + HttpUtility.UrlEncode("Example");
도움이 되길 바랍니다.또한, 시드데이가 언급한 대로 잘못된 파일 이름 문자가 제거되었는지 확인해야 합니다. 그렇지 않으면 파일 시스템이 경로를 좋아하지 않을 것입니다.
더 좋은 방법은 사용하는 것입니다.
.net 4의 전체 프로필을 참조하지 않습니다.
[업데이트]
OP가 요구하는 것에 근거하여, 권장되는 API는 다음과 같아야 합니다.
(감사합니다 @ykadaru)
편집: 이 답변은 이제 구식입니다.더 나은 해결책은 아래의 Siarhei Kuchuk의 답변을 참조하십시오.
UrlEncoding은 당신이 여기서 제안하는 것을 할 것입니다.C#을 사용하면 다음과 같이 간단하게HttpUtility상술한 바와 같이
잘못된 문자를 정규식으로 바꾼 다음 교체할 수도 있지만 올바른 문자로 대체하려면 어떤 형태로든 상태 기계(예: 스위치... 대/소문자)가 있어야 하기 때문에 훨씬 더 복잡해집니다. 때부터UrlEncode이것을 앞에서 하면, 그것은 오히려 쉽습니다.
Windows의 되지 않는 가 몇 개 폴더 할 수 .UrlDecode변경 사항을 왕복할 수 있습니다.
.NET Framework 4.5 및 이후 버전.NET Standard 1.0을 사용해야 합니다. 대안에 비해 장점:
의 일부입니다.NET Framework 4.5+, .NET Core 1.0+, .NET Standard 1.0+, UWP 10.0+ 및 모든 Xamarin 플랫폼도 에서 사용할 수 있습니다.이전 버전의 NET Framework(.NET Framework 1.1+)은 나중에 다른 플랫폼에서 사용할 수 있게 됩니다.NET Core 2.0+, .NET Standard 2.0+) 및 UWP에서는 여전히 사용할 수 없습니다(관련 질문 참조).
.NET Framework에서는 에 상주하기 때문에 추가 참조가 필요하지 않습니다.
HttpUtility.이 경우와 달리 URL에 대한 문자를 제대로 이스케이프합니다.
Uri.EscapeUriString(drweb86의 답변에 대한 주석 참조).문자열의 길이에 대한 제한은 없습니다.
Uri.EscapeDataString(관련 질문 참조), 예를 들어 POST 요청에 사용할 수 있습니다.
Levi Botelho는 이전에 생성된 인코딩 표가 더 이상 정확하지 않다고 언급했습니다.NET 4.5, 인코딩이 사이에서 약간 변경되었기 때문입니다.NET 4.0 및 4.5.그래서 테이블을 재생성했습니다.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 " " " %22
# %23 %23 # %23 %23 # # # # %23
$ %24 %24 $ %24 %24 $ $ $ $ %24
% %25 %25 % %25 %25 %25 % % % %25
& %26 %26 & %26 %26 & & & & %26
' %27 %27 ' %27 %27 ' ' ' ' %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 < < < %3C
= %3d %3d = %3D %3D = = = = %3D
> %3e %3e > %3E %3E %3E > > > %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]
열은 다음과 같이 인코딩을 나타냅니다.
- 인코딩된 URL:
HttpUtility.UrlEncode - URL 인코딩유니코드:
HttpUtility.UrlEncodeUnicode - UrlPathEncoded:
HttpUtility.UrlPathEncode - WebUtilityUrl 인코딩:
WebUtility.UrlEncode - 이스케이프된 데이터 문자열:
Uri.EscapeDataString - 이스케이프된 UriString:
Uri.EscapeUriString - Html 인코딩:
HttpUtility.HtmlEncode - Html 특성 인코딩:
HttpUtility.HtmlAttributeEncode - WebUtilityHtml 인코딩:
WebUtility.HtmlEncode - 16진수 이스케이프:
Uri.HexEscape
주의:
HexEscape는 처음 255자만 처리할 수 있습니다.따라서 Latin A-Extended 문자(예: AAA)에 대해 Argument Out Of Range 예외를 발생시킵니다.
이 테이블은 에서 생성되었습니다.NET 4.5 (관련 인코딩은 https://stackoverflow.com/a/11236038/216440 참조).NET 4.0 이하).
편집:
- Discord의 답변에 따라 에서 도입된 새로운 WebUtilityUrlEncode 및 HtmlEncode 메서드를 추가했습니다.NET 4.5.
URL 인코딩은 에서 쉽게 수행할 수 있습니다.NET. 사용:
System.Web.HttpUtility.UrlEncode(string url)
폴더 이름을 가져오기 위해 디코딩되는 경우에도 폴더 이름(*, ?, / 등)에 사용할 수 없는 문자는 제외해야 합니다.
시스템이 표시되지 않는 경우.웹에서 프로젝트 설정을 변경합니다.대상 프레임워크는 "."이어야 합니다.." 대신 NET Framework 4".NET Framework 4 클라이언트 프로필"
의 .NET 구현UrlEncodeRFC 3986을 준수하지 않습니다.
일부 문자는 인코딩되지 않았지만 인코딩되어야 합니다.그
!()*문자는 아직 인코딩되어야 하는 예약된 문자로 RFC의 섹션 2.2에 나열되어 있습니다.NET이 이러한 문자를 인코딩하지 못했습니다.일부 문자는 인코딩되지만 인코딩되어서는 안 됩니다.그
.-_문자는 아직 인코딩해서는 안 되는 예약된 문자로 RFC의 섹션 2.2에 나열되어 있지 않습니다.NET은 이러한 문자를 잘못 인코딩합니다.RFC는 일관성을 유지하기 위해 구현에 대문자 HEXDIG를 사용해야 한다고 지정합니다.NET은 소문자 HEXDIG를 생산합니다.
여기 사람들은 UrlEncode 메시지에 의해 옆길로 빠져나간 것 같습니다.URL 인코딩은 원하는 것이 아닙니다. 대상 시스템에서 파일 이름으로 작동하지 않는 항목을 인코딩하려고 합니다.
일부 일반성을 원한다고 가정하면, 여러 시스템(MacOS, Windows, Linux 및 Unix)에서 잘못된 문자를 자유롭게 찾을 수 있습니다. 이 문자들을 결합하여 탈출할 문자 집합을 구성합니다.
이스케이프의 경우, HexEscape가 괜찮을 것입니다(문자를 %XX로 대체).유니코드를 실행하지 않는 시스템을 지원하려면 각 문자를 UTF-8바이트로 변환하고 128 이상의 모든 문자를 인코딩합니다.그러나 백슬래시 "\" 또는 HTML 인코딩 ""와 같은 다른 방법이 있습니다.직접 만들 수 있습니다.시스템이 해야 할 일은 호환되지 않는 문자를 '인코딩'하는 것입니다.위의 시스템을 사용하면 원래 이름을 다시 만들 수 있습니다. 하지만 잘못된 문자를 공백으로 대체하는 것과 같은 것도 작동합니다.
위와 같은 탄젠트에서 사용할 수 있는 유일한 탄젠트는
Uri.EscapeDataString
OAuth에 필요한 모든 것을 인코딩하고, OAuth가 인코딩을 금지하는 것을 인코딩하지 않으며, 공간을 +가 아닌 %20으로 인코딩합니다(WEASE 사양에서도 참조). RFC 3986AFAIK, 이것은 최신 URI 사양입니다.
나는 모든 기호를 url 인코딩하는 C# 메소드를 작성했습니다.
/// <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();
}
이상적으로는 "FileNaming"이라는 클래스에 들어가거나 Encoding의 이름을 "FileNameEncode"로 바꾸는 것이 좋습니다.참고: 전체 경로를 처리하도록 설계된 것이 아니라 폴더 및/또는 파일 이름만 처리하도록 설계되었습니다.이상적으로는 먼저 전체 경로를 분할("/")한 다음 조각을 확인합니다.그리고 분명히 조합 대신 Windows에서 허용되지 않는 문자 목록에 "%" 문자를 추가할 수 있지만, 이 방법이 더 유용하고 읽기 쉬우며 사실적이라고 생각합니다.디코딩()은 정확히 동일하지만 Replace(Uri)를 전환합니다.HexEscape(s[0]), s) 문자와 함께 "excape"됩니다.
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;
}
위의 매우 유용한 테이블에 대해 @simon-tewsi에게 감사드립니다!
@Dan Herbert의 대답 외에도, 우리는 일반적으로 값만 인코딩해야 합니다.
분할에는 매개 변수 분할('&','=')이 있습니다. 식은 먼저 >로 분할된 다음 '='로 분할되므로 홀수 요소는 아래에 표시된 모든 값으로 인코딩됩니다.
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);
}
}
}
.net 코어 사용자의 경우 다음을 사용합니다.
Microsoft.AspNetCore.Http.Extensions.UriHelper.Encode(Uri uri)
언급URL : https://stackoverflow.com/questions/575440/url-encoding-using-c-sharp
'programing' 카테고리의 다른 글
| Terraformazure 상태 파일을 다른 구독으로 보유 중 (0) | 2023.05.07 |
|---|---|
| 프록시를 인스턴스화할 수 없습니다...매개 변수 없는 생성자를 찾을 수 없습니다. (0) | 2023.05.07 |
| 여러 커밋을 다른 분기에 단일 스퀴시 커밋으로 병합하려면 어떻게 해야 합니까? (0) | 2023.05.07 |
| Bash 내부에서 Emacs를 여는 방법 (0) | 2023.05.07 |
| 이름을 알 수 없는 서비스가 Ubuntu에서 실행되고 있는지 확인하는 방법 (0) | 2023.05.07 |