バックグラウンド転送を使用して、写真を Web サービスにアップロードしています。写真のアップロードはかなりの時間とメモリを消費する可能性があるため、バックグラウンド転送リクエストを使用してこれを達成するのは良い考えだと思いました。写真がアップロードされた後、アップロードされた写真の Id を取得し、それを後処理に使用したいと考えています。しかし、バックグラウンド転送リクエストではそれができないことがわかりました。
私の理解では、バックグラウンド転送は次のロジックのみを使用して機能します。
アップロードするファイルを取得し、アプリの分離ストレージのshared/transfersフォルダーに保存/コピーする必要があります。これは非常に重要です。どうやら、別の場所にあるファイルを使用してもうまくいきませんでした。たぶん、それは「相対」パスであるほど共有/転送ではありません。しかし、私は同じ慣習に固執します。
その場所にファイルを保存したら、それに基づいてバックグラウンド リクエストを作成できます。ファイルの内容以外に POST CONTENT を渡すことができないように見えるため、ファイル名、MIME タイプなどの他のパラメーターは、QUERY 文字列パラメーターとしてのみ渡す必要があります。これは理解できますが、両方を POST Content として渡すことができればよかったのにと思います。これがどのように機能するかについて、HTTP に制限があるとは思いません。
Hammock を使用してリクエストを作成するためのコードを次に示します。
string url = App.ZineServiceAuthority + "articles/save-blob?ContainerName={0}&MimeType={1}&ZineId={2}&Notes={3}&IsPrivate={4}&FileName={5}";
url = String.Format(url, userId, "image/jpg", ZineId, txtStatus.Text, true, UploadFileName);
var btr = new BackgroundTransferRequest(new Uri(url, UriKind.Absolute));
btr.TransferPreferences = TransferPreferences.AllowCellularAndBattery;
btr.Method = "POST";
btr.Headers.Add("token", IsolatedStorageHelper.GetTravzineToken());
btr.UploadLocation = new Uri(@"/shared\transfers/" + UploadFileName, UriKind.Relative);
btr.TransferStatusChanged += new EventHandler<BackgroundTransferEventArgs>(btr_TransferStatusChanged);
btr.TransferProgressChanged += new EventHandler<BackgroundTransferEventArgs>(btr_TransferProgressChanged);
BackgroundTransferService.Add(btr);
私の場合、文字通り、クエリ文字列を使用して必要なすべてのパラメーターを渡しています。保存が成功すると、アップロードしたばかりの写真の ID が Web サービスから返されます。ただし、応答を取得して評価する方法はありません(または少なくとも私が知っています)。バックグラウンド転送要求イベント ハンドラーは、RESPONSE を公開しません。ここに私のイベントハンドラがあります:
void btr_TransferProgressChanged(object sender, BackgroundTransferEventArgs e)
{
bool isUploading = e.Request.TotalBytesToSend > 0 ? true : false;
lblStatus.Text = isUploading ? "Uploading" + e.Request.BytesSent.ToString() + " sent" : "Done";
}
void btr_TransferStatusChanged(object sender, BackgroundTransferEventArgs e)
{
if (e.Request.TransferStatus == TransferStatus.Completed)
{
using (IsolatedStorageFile iso =
IsolatedStorageFile.GetUserStoreForApplication())
{
if (iso.FileExists(e.Request.UploadLocation.OriginalString))
iso.DeleteFile(e.Request.UploadLocation.OriginalString);
}
BackgroundTransferService.Remove(e.Request);
if (null != e.Request.TransferError)
{
MessageBox.Show(e.Request.TransferError.Message);
}
else
{
lblStatus.Text = "Done baby done";
}
}
}
だから今私の質問は、そのようなシナリオで誰かがどのように POST 処理を行うのですか? このような柔軟性のないクラスを設計する背後にある考え方を誰か教えてもらえますか? この問題を回避する方法についての考えをいただければ幸いです。
また、自家製の BackgroundTransfer の実例はありますか?