본문 바로가기

옛것

UrlEncode함수를 프레임워크 .NET Client Profile에서 사용하기 (VB .NET)


URL 인코딩 기능은 많은곳에서 필요합니다. 특히 한글이나 특수문자를 URL을 통해 전송할 때 필요한데요,

아쉽게도 이 함수는 프레임워크 .NET의 Client Profile에 포함되어 있지 않습니다.


고로 이 함수를 사용하기 위해서는 Client Profile로 컴파일을 하면 안됩니다.

하지만 Windows 7 이상에는 Fw .NET 4.0 Client Profile가 기본적으로 설치되어있습니다.
VISTA이하라면 4.0 이상은 설치를 해야하지만, 7의 경우 기본적으로 CP가 깔려있기때문에 또 4.0을 따로 설치하라고하면 뭔가 미안하기도 하고, 사용자의 입장에서는 귀찮기도 합니다.

그래서 알아냈습니다, Client Profile 컴파일로도 UrlEncode함수를 사용하는 방법을.


별건 아니고, .NET Reflector를 통해 UrlEncode함수를 그냥 따왔습니다.


일단 모듈 하나 추가하시구요

모듈에 아래 코드를 붙여넣습니다. (VB기준, C#은 코드변환기를 이용해보세요)

Public Function UrlEncode(ByVal str As String) As String
        If (str Is Nothing) Then
            Return Nothing
        End If
        Return UrlEncode(str, Encoding.Default)
    End Function

    Private Function UrlEncode(ByVal str As String, ByVal e As Encoding) As String
        If (str Is Nothing) Then
            Return Nothing
        End If
        Return Encoding.ASCII.GetString(UrlEncodeToBytes(str, e))
    End Function

    Private Function UrlEncodeToBytes(ByVal str As String, ByVal e As Encoding) As Byte()
        If (str Is Nothing) Then
            Return Nothing
        End If
        Dim bytes As Byte() = e.GetBytes(str)
        Return UrlEncodeBytesToBytesInternal(bytes, 0, bytes.Length, False)
    End Function

    Private Function IsSafe(ByVal ch As Char) As Boolean
        If ((((ch >= "a"c) AndAlso (ch <= "z"c)) OrElse ((ch >= "A"c) AndAlso (ch <= "Z"c))) OrElse ((ch >= "0"c) AndAlso (ch <= "9"c))) Then
            Return True
        End If
        Select Case ch
            Case "'"c, "("c, ")"c, "*"c, "-"c, "."c, "_"c, "!"c
                Return True
        End Select
        Return False
    End Function
    Private Function UrlEncodeBytesToBytesInternal(ByVal bytes As Byte(), ByVal offset As Integer, ByVal count As Integer, ByVal alwaysCreateReturnValue As Boolean) As Byte()
        Dim num As Integer = 0
        Dim num2 As Integer = 0
        Dim i As Integer
        For i = 0 To count - 1
            Dim ch As Char = ChrW(bytes(offset + i))
            If (ch = " "c) Then
                num += 1
            ElseIf Not IsSafe(ch) Then
                num2 += 1
            End If
        Next i
        If ((Not alwaysCreateReturnValue AndAlso (num = 0)) AndAlso (num2 = 0)) Then
            Return bytes
        End If
        Dim buffer As Byte() = New Byte((count + (num2 * 2)) - 1) {}
        Dim num4 As Integer = 0
        Dim j As Integer
        For j = 0 To count - 1
            Dim num6 As Byte = bytes(offset + j)
            Dim ch2 As Char = ChrW(num6)
            If IsSafe(ch2) Then
                buffer(num4) = num6
                num4 += 1
            ElseIf (ch2 = " "c) Then
                buffer(num4) = &H2B
                num4 += 1
            Else
                buffer(num4) = &H25
                num4 += 1
                buffer(num4) = CByte(AscW(IntToHex((num6 >> 4) And 15)))
                num4 += 1
                buffer(num4) = CByte(AscW(IntToHex(num6 And 15)))
                num4 += 1
            End If
        Next j
        Return buffer
    End Function
    Private Function IntToHex(ByVal n As Integer) As Char
        If (n <= 9) Then
            Return ChrW(n + &H30)
        End If
        Return ChrW((n - 10) + &H61)
    End Function

UrlEncode함수를 사용하기 위한 모든 함수를 옮겨놨습니다.

아, System.Text를 임포트(imports)해주세요. Encoding 클래스를 불러오기 위함입니다.

지금 이 코드의 문자 인코딩은 기본(Default)입니다. 만약 다른 인코딩(UTF-8이라던지)을 사용하실분은 위 코드의 윗부분에 두꺼운글씨로 'default'라 쓰여있는부분을 다른 인코딩 형식으로 바꿔주시면 됩니다.


사용법은

모듈이름.UrlEncode("문자열")

입니다.

만약 기본으로 지정된 인코딩 외 다른 인코딩을 써서 URL인코딩을 하고싶다면

모듈이름.UrlEncode("문자열", 인코딩)

이 되겠네요.
한국어 인코딩은 Encoding.GetEncoding(949)입니다. (euc-kr) 만약 글자가 깨진다면 인코딩을 바꿔보세요.



위 예제는 모두 VB .NET을 기준으로 작성되었구요, VB .NET의 코드는 C#의 코드로 상호변환이 가능하므로 C#프로그래머분들은 위 코드를 C#코드로 변환하신 후에 사용하시면 됩니다.