#windows-phone-7 #wcf-web-api
#windows-phone-7 #wcf-web-api
Вопрос:
Я использую фоновую передачу для загрузки фотографий в свою веб-службу. Поскольку загрузка фотографий может занимать значительное время и память, я подумал, что было бы неплохо использовать для этого запрос на фоновую передачу. После загрузки фотографии я хочу получить идентификатор загруженной фотографии, а затем использовать ее для последующей обработки. Однако, оказывается, я не могу сделать это в запросе фоновой передачи.
Насколько я понимаю, фоновая передача работает ТОЛЬКО по следующей логике:
- Вы должны получить файл, который хотите загрузить, а затем сохранить / скопировать его в изолированное хранилище вашего приложения в папке: общие / передачи. Это чрезвычайно важно. По-видимому, использование файла в другом месте не сработало для меня. Возможно, это не столько общий / transfers, сколько «относительный» путь. Но я бы придерживался тех же соглашений.
- После сохранения файла в этом расположении на его основе можно создать фоновый запрос. Не похоже, что вы можете передавать СОДЕРЖИМОЕ POST, отличное от содержимого файла, поэтому любые другие параметры, такие как имя файла, тип mime и т. Д. необходимо будет передавать только в качестве параметров строки запроса. Я могу это понять, но было бы неплохо, если бы я мог передать оба в качестве содержимого публикации. Я не думаю, что HTTP имеет ограничение на то, как это работает.
Вот некоторый код для создания запроса с использованием Hammock:
string url = App.ZineServiceAuthority "articles/save-blob?ContainerName={0}amp;MimeType={1}amp;ZineId={2}amp;Notes={3}amp;IsPrivate={4}amp;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(@"/sharedtransfers/" UploadFileName, UriKind.Relative);
btr.TransferStatusChanged = new EventHandler<BackgroundTransferEventArgs>(btr_TransferStatusChanged);
btr.TransferProgressChanged = new EventHandler<BackgroundTransferEventArgs>(btr_TransferProgressChanged);
BackgroundTransferService.Add(btr);
В моем случае я буквально передаю все необходимые параметры, используя строку запроса. При успешном сохранении мой веб-сервис возвращает идентификатор фотографии, которую я только что загрузил. Однако:
Нет способа (или, по крайней мере, я знаю) получить и оценить ОТВЕТ. Обработчики событий запроса фоновой передачи не предоставляют ОТВЕТ.
Вот мои обработчики событий:
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";
}
}
}
Итак, теперь мой вопрос в том, как кто-нибудь выполняет какую-либо постобработку в таких сценариях?
Может кто-нибудь, пожалуйста, рассказать мне о том, что стоит за разработкой такого негибкого класса?
Буду признателен за любые мысли о том, как я мог бы обойти эту проблему.
Кроме того, есть ли у кого-нибудь рабочие примеры доморощенного BackgroundTransfer?
Ответ №1:
Не пробовал, но почему бы не указать место загрузки следующим образом:
btr.DownloadLocation = "myDownloadFile.html";
btr.UploadLocation = "myUploadFile.jpg";
...
Если запрос завершен, прочитайте файл «myDownloadFile.html » где был сохранен ваш ответ, а затем удалите его.
Комментарии:
1. Интересный подход, если я правильно понимаю, вы говорите, что после сохранения файла мне, возможно, следует создать текстовый файл с ответом? Хм. Интересно, насколько хорошо это будет работать, когда у меня будет 100 загрузок фотографий.
2. Я думаю, что это единственный способ получить ответ => запись в файл. Конечно, если у вас есть несколько загрузок, файл должен иметь уникальное имя файла (например, используйте время начала запроса
DateTime.Now.Ticks
в качестве имени файла). Этот выходной файл ответа очень маленький, поэтому он не должен вызывать проблем с производительностью. Это работает для вас?3. Я думаю, что я собираюсь отказаться от использования службы фоновой передачи. Это не кажется хорошей идеей. Я думаю, что я напишу свой собственный обработчик таким образом, чтобы он записывал байты в веб-службу из изолированного хранилища, а затем, если процесс остановится на полпути, его придется перезапускать заново. Печально, что никто в Microsoft не подумал об этом достаточно хорошо.
4. Хорошо, я согласен с вашей идеей, но идея иметь файлы ответов и дополнительные накладные расходы на управление ими мне не кажется очень привлекательной. Однако я не знаю, позволяет ли та же задача загружать / загружать. Возможно, мне потребуется создать другую задачу, которая запускает загрузку. Я буду держать вас в курсе.
5. Здравствуйте, хотел сообщить вам об этом. Я не думаю, что вы можете выполнить ЗАГРУЗКУ и ЗАГРУЗКУ одновременно таким образом в одном вызове, поэтому то, что вы упомянули выше, не будет работать. Тем не менее, спасибо за ваш ответ.