On the project that I am currently working, I need to send SMS messages. Sending SMS'es is easy enough - you just call the URL of your chosen provider with your username etc. billing-information and then of course the text message for the SMS as part of the URL.
But guess what - ASP.NET's own UrlEncode is set up for converting to UTF-8, and the SMS provider of course wants text in codepage 1252 - otherwise the special danish letters (like "øæå") gets lost.
It might be possible to configure the website to use that codepage, but really - it is only this one single call that needs that special codepage, and I prefer the rest of the website using UTF-8.
Well, some google'ing and I found a Visual Basic code for old ASP websites to do the conversion, and I decided to take that piece and rewrite it for ASP.NET and C# - and since the original was open source, here follows my routine as open source too:
public static string WindowsEncodeUrl(string wideStr)
Encoding winEncoding = Encoding.GetEncoding(1252);
Encoding unicode = Encoding.Unicode;
byte unicodeBytes = unicode.GetBytes(wideStr);
byte winBytes = Encoding.Convert(unicode, winEncoding, unicodeBytes);
StringBuilder outStr = new StringBuilder();
for (int i = 0; i < wideStr.Length && i < winBytes.Length; i++)
char cLet = wideStr[i];
byte bLet = winBytes[i];
if (bLet == 32)
else if (bLet < 48 || bLet > 126 || (bLet > 56 && bLet <= 64))
outStr.Append("%" + winBytes[i].ToString("X2"));
Note: The algorithm was as I said copied from another site, so I don't know if the number comparisons are correct for all European languages, but as far as I have tested it, it seams to work fine for Danish. If you need conversion for a different codepage, you can of course just change it in the above code, but be aware that this code will not work for languages or codepage that might include double bytes or double words.
Updated the 14th may 2011:
Now I needed the conversion the other way - my website was called with an URL, where the arguments was in CodePage 1252 instead of UTF-8. And after fumbling around I found the must simpler solution inside an ashx handler:
context.Request.ContentEncoding = System.Text.Encoding.GetEncoding(1252);
string smsMsg = context.Server.UrlDecode(context.Request.QueryString["msg"]);
Or in other words: Setting the code page of the incoming request made the QueryString and UrlDecode work together in such a way that nothing else was needed!
Now, I wonder if my first piece of code was similar unnecessary... Oh well, you "live and learn".