読者です 読者をやめる 読者になる 読者になる

tmytのらくがき

個人の日記レベルです

BackgroundTransferServiceで画像のアップロードみたいな感じ

WP7 Dev

MangoからBackgroundTransferServiceってのでアプリが死んでる間でもOSがなんとなーく回線の隙間を見つけてHTTP通信してくれるのが追加されてうれしい感じ。
というわけでそれを使ってアップロードしてみる。というおはなし。

private string CreateMultipartFormData(Dictionary<string, object> Params, string boundary)
{
    StringBuilder sb = new StringBuilder();

    foreach (var p in Params)
    {
        // Header
        sb.AppendFormat("--{0}\r\n", boundary);
        // Body
        if (p.Value is Stream)
        {
            Stream stream = p.Value as Stream;
            stream.Seek(0, SeekOrigin.Begin);
            StreamReader sr = new StreamReader(stream, Encoding.GetEncoding("ISO-8859-1"));
            sb.AppendFormat("Content-Disposition: file; name=\"{0}\"; filename=\"CapturedFile.jpg\"\r\n\r\n", p.Key);
            sb.AppendLine(sr.ReadToEnd());
        }
        else
        {
            sb.AppendFormat("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n", p.Key);
            byte[] dataBytes = Encoding.UTF8.GetBytes(p.Value.ToString());
            sb.AppendLine(Encoding.GetEncoding("ISO-8859-1").GetString(dataBytes, 0, dataBytes.Length));
        }
        // Footer
    }
    sb.AppendFormat("--{0}--\r\n", boundary);
    return sb.ToString();
}

public void ExecTransfer(string requestUrl, Dictionary<string, object> Params)
{
    string boundary = Guid.NewGuid().ToString();
    string bodyFile = "/shared/transfers/" + boundary + ".postdata";
    string contents = CreateMultipartFormData(Params, boundary);

    // IsolatedStorageへ書き出し
    byte[] bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(contents.ToString());
    using (var ifs = IsolatedStorageFile.GetUserStoreForApplication())
    {
        // BackgroundTransfer用のディレクトリを作成
        if (!ifs.DirectoryExists("/shared")) ifs.CreateDirectory("/shared");
        if (!ifs.DirectoryExists("/shared/transfers")) ifs.CreateDirectory("/shared/transfers");
        // リクエストデータの保存
        using (var stream = new IsolatedStorageFileStream(bodyFile, FileMode.Create, ifs))
        {
            stream.Write(bytes, 0, bytes.Length);
            stream.Flush();
        }
    }

    // BackgroundTransferサービスへ投げつける
    var req = new BackgroundTransferRequest(new Uri(requestUrl));
    req.UploadLocation = new Uri(bodyFile, UriKind.Relative);
    req.Method = "POST";
    req.Headers["Content-Type"] = string.Format("multipart/form-data; boundary={0}", boundary);
    req.TransferPreferences = TransferPreferences.AllowCellularAndBattery;
    BackgroundTransferService.Add(req);
}

// ためしに送信してみる
void UploadPhoto()
{
    Dictionary<string, object> prms = new Dictionary<string, object>();
    using (var ifs = IsolatedStorageFile.GetUserStoreForApplication())
    {
        using (var stream = new IsolatedStorageFileStream("/sample.jpg", FileMode.Open, ifs))
        {
            prms["username"] = "hoge";
            prms["image"] = stream;
            ExecTransfer("http://example.com/upload.cgi", prms);
        }
    }
}