tags:

views:

805

answers:

4

Hi, I'm working on a data transfer for a gateway which requires me to send data in UrlEncoded form. However, .net's UrlEncode creates lowercase tags, and it breaks the transfer (Java creates uppercase).

Any thoughts how can I force .net to do uppercase UrlEncoding?

update1:

.net out:

dltz7UK2pzzdCWJ6QOvWXyvnIJwihPdmAioZ%2fENVuAlDQGRNCp1F

vs Java's:

dltz7UK2pzzdCWJ6QOvWXyvnIJwihPdmAioZ%2FENVuAlDQGRNCp1F

(it is a base64d 3DES string, i need to maintain it's case).

+7  A: 

I think you're stuck with what C# gives you, and getting errors suggests a poorly implemented UrlDecode function on the other end.

With that said, you should just need to loop through the string and uppercase only the two characters following a % sign. That'll keep your base64 data intact while massaging the encoded characters into the right format:

public static string UpperCaseUrlEncode(string s)
{
  char[] temp = HttpUtility.UrlEncode(s).ToCharArray();
  for (int i = 0; i < temp.Length - 2; i++)
  {
    if (temp[i] == '%')
    {
      temp[i + 1] = char.ToUpper(temp[i + 1]);
      temp[i + 2] = char.ToUpper(temp[i + 2]);
    }
  }
  return new string(temp);
}
Iceman
thanks, but the question was rather about RFC compliance and implementation.
balint
@balint, the relevant RFCs say that you can use upper or lower case for escaped characters in the URL, which is why errors with lower case suggest a bad implementation on the decoding end. However, the above C# code will produce the same results as Java's UrlEncode, so unless I misunderstand the question it should be exactly what you need.
Iceman
Even though the spec says either is ok, It still makes a huge difference when the encoded string is part of an input into a Hashing routine :-(
Tim Jarvis
A: 

This is the code that I'm using in a Twitter application for OAuth...

    Public Function OAuthUrlEncode(ByVal value As String) As String
    Dim result As New StringBuilder()
    Dim unreservedChars As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~"
    For Each symbol As Char In value
        If unreservedChars.IndexOf(symbol) <> -1 Then
            result.Append(symbol)
        Else
            result.Append("%"c + [String].Format("{0:X2}", AscW(symbol)))
        End If
    Next

    Return result.ToString()
End Function

Hope this helps!

DWRoelands
+1  A: 

be aware that the code (OAuthUrlEncode) in DWRoelands' answer will cause You problems with international characters!

Dov
A: 

Replace the lowercase percent encoding from HttpUtility.UrlEnocde with a Regex:

static string UrlEncodeUpperCase(string value) {
    value = HttpUtility.UrlEncode(value);
    return Regex.Replace(value, "(%[0-9a-f][0-9a-f])", c => c.Value.ToUpper());
}

var value = "SomeWords 123 #=/ äöü";

var encodedValue = HttpUtility.UrlEncode(value);
// SomeWords+123+%23%3d%2f+%c3%a4%c3%b6%c3%bc

var encodedValueUpperCase = UrlEncodeUpperCase(value);
// now the hex chars after % are uppercase:
// SomeWords+123+%23%3D%2F+%C3%A4%C3%B6%C3%BC
Meixger