twitter の status/update_with_media で日本語を扱えない

Category: windows phone apps_ja

Question

SunSkySoft on Tue, 30 Apr 2013 09:37:55


Windows Phone 7.x の twitter クライアントを作っていますが、status/update では日本語を正しく表示させることができますが、status/update_with_media では日本語が正しく表示できません。

 

たとえば、"テスト" という文章を画像とともに送ると、twitter では以下の表に表示されます。

 %E3%83%86%E3%82%B9%E3%83%88 pic.twitter.com/xxxxxx

 

twitter api へのアクセスには hammock を利用し、以下のコードを書いています。

何が足りないのでしょうか?

var client = new Hammock.RestClient()
{
    Authority = "https://api.twitter.com/",
    VersionPath = "1.1",
    HasElevatedPermissions = true,
    Method = Hammock.Web.WebMethod.Post,
    Credentials = new Hammock.Authentication.OAuth.OAuthCredentials()
    {
        ConsumerKey = OAuthTwit.CONSUMER_KEY,
        ConsumerSecret = OAuthTwit.CONSUMER_SECRET,
        Token = oauth_token,
        TokenSecret = oauth_token_secret,
        Type = Hammock.Authentication.OAuth.OAuthType.ProtectedResource
    }
};
var request = new Hammock.RestRequest();
request.Path = "statuses/update_with_media.json";
request.AddField("status", UrlEncode(MyStatus));
request.AddFile("media[]", "TempJPEG.jpg", "TempJPEG.jpg", "image/jpeg");
client.BeginRequest(request, new Hammock.RestCallback(PostedStatus));


SunSkySoft

Replies

こくぶん on Wed, 08 May 2013 04:13:13


※当方は Hammock を利用していないので、下記内容は未検証です。

「%E3%83%86%E3%82%B9%E3%83%88」は「テスト」を UrlEncode した文字列と等価なので、パラメータ値に対して UrlEncode が二重に適用されているのではないかと思われます。

実際、 Hammock の内部コードを見ると、 Post 送信されるデータのパラメータ値に対して内部で UrlEncode を適用している様なので、request.AddField に元の値のまま( UrlEncode を適用せずに)設定すればいけませんでしょうか。

request.AddField("status", MyStatus);

Masahiro Kokubun


SunSkySoft on Mon, 13 May 2013 04:35:53


Kokubun さん、返信ありがとうございます。

request.AddField("status", MyStatus); では、MyStatus が Unicode であるため、結果は "???" と表示されます。

 

いろいろ調べた結果、update_with_media の status の値は、URLエンコードせずに UTF-8 で出力しなければいけないことがわかりました。

 

Hammock のソースを見てみると、

        private long WriteMultiPartImpl(bool write, IEnumerable<HttpPostParameter> parameters, string boundary, Encoding encoding, Stream requestStream)
        {
            Stream fs = null;
            var header = string.Format("--{0}", boundary);
            var footer = string.Format("--{0}--", boundary);
            long written = 0;

            foreach (var parameter in parameters)
            {
                written += WriteLine(write, encoding, requestStream, header);
                switch (parameter.Type)
                {
                    case HttpPostParameterType.Field:
                        {
                            var fieldLine = "Content-Dis name=\"{0}\"".FormatWith(parameter.Name);
                            
                            written += WriteLine(write, encoding, requestStream, fieldLine);
                            written += WriteLine(write, encoding, requestStream, "");
                            written += WriteLine(write, encoding, requestStream, parameter.Value);

                            break;
                        }
                }
            }

となっており、Encoding.GetEncoding("ISO-8859-1") で必ずエンコードされてしまいます。

 

対策としては、Hammock にマルチパートの処理を任せずに自分で書くか、上記コードの

written += WriteLine(write, encoding, requestStream, parameter.Value);

の parameter.Value を UTF-8 に変換するように修正するしかないようです。

 

私はとりあえず、上記部分を UTF-8 で出力するように変更することにして、日本語が正しく表示されるようになりました。

この対策により、同じようにマルチパートで出力していた Twitpic の日本語文字化けも修正されました。