2013/09/07

【C#でTwitter】HttpUtility.UrlEncodeを使う時の罠

 随分前に勉強のため、C#のTwitter用ライブラリを作成していた。
しかし、どうやっても「401:認証エラー」になってしまった。


その原因は「HttpUtillity.UrlEncode」にあった。



原因と対策



原因



「HttpUtillity.UrlEncode」を使用するとエンコード結果が小文字で返ってくる


対策


エンコード結果を大文字にしてあげれば良い。

protected string unreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";

protected string UrlEncode(string value)
 {
     StringBuilder result = new StringBuilder();

     foreach (char symbol in value)
     {
         if (unreservedChars.IndexOf(symbol) != -1)
         {
             result.Append(symbol);
         }
         else
         {
             result.Append('%' + String.Format("{0:X2}", (int)symbol));
         }
     }

     return result.ToString();
}

これでいいらしい。(OAuthBase.csから引用)
Urlを1文字ずつ見て、unreservedCharsにないものはエンコードといったかたち。



これじゃマルチバイトに対応できない?



エンコードについてググったら上記の対応ではマルチバイト文字が使用できないという記事を見つけた。


http://d.hatena.ne.jp/nyanp/20100504/p1
Lagrangian point L2 - OAuthとC#でマルチバイト文字を扱う








こんな感じにしてあげれば良いみたい。
文字コードはUTF-8でいいと思うので、 他を修正するのも面倒だからオーバーロードを追加



protected string UrlEncode(string value)
{
    return UrlEncode(value, Encoding.UTF8);
}

protected string UrlEncode(string value, Encoding encode)
{
    StringBuilder result = new StringBuilder();
    byte[] data = encode.GetBytes(value);

    int len = data.Length;

    for (int i = 0; i < len; i++)
    { 
        int c = data[i]; 
        if (c < 0x80 && unreservedChars.IndexOf((char)c) != -1) 
        {
            result.Append((char)c); 
        }
        else
        {
            result.Append('%' + String.Format("{0:X2}", (int)data[i])); 
        } 
    
    }
    return result.ToString();
}




以上

0 件のコメント :

コメントを投稿