#c# #silverlight #mvvm-light
#c# #серебристый свет #mvvm-light #silverlight
Вопрос:
Так что, должно быть, я делаю здесь что-то не так, просто пока не уверен, что именно. Мой оригинальный PoC работал нормально, но не был MVVM, поэтому я кое-что потерял в переводе.
Итак, я просматриваю файл, который нужно выбрать для загрузки, все начинает работать нормально. Он передает первый фрагмент на сервер, а затем мое полное событие никогда не вызывается. И это приведет к отправке всех дополнительных фрагментов в массиве, поэтому файл будет неполным.
Я просто пропустил шаг?
И если это имеет значение, служба настроена на IIS7, но я не уверен, нужно ли что-то настраивать на стороне службы, чтобы это произошло. Он просто «работал» в коде PoC, когда я использовал код XAML.
Код модели:
public void uploadChunks(int index, string fileName)
{
FileUpload fileUpload = new FileUpload();
FileUpload.FileName = fileName;
FileUpload.chunk = fileChunks[index];
context.UploadFileAsync(fileUpload);
}
FileUploadServiceSoapClient context = new FileUploadServiceSoapClient("BasicHttpBinding_FileUploadServiceSoap");
int chunkSize = 15306;
public List<byte[]> fileChunks;
public double TotalChunks { get; set; }
/// <summary>
/// Convert file to an array of file chunks to stream to the upload location
/// </summary>
/// <param name="imageFile"></param>
public void convertToChunks(byte[] imageFile)
{
TotalChunks = Math.Ceiling((double)imageFile.Length / (double)chunkSize);
fileChunks = new List<byte[]>();
for (int i = 0; i < TotalChunks; i )
{
byte[] chunk;
int startIndex = i * chunkSize;
if (startIndex chunkSize > imageFile.Length)
chunk = new byte[imageFile.Length - startIndex];
else
chunk = new byte[chunkSize];
Array.Copy(imageFile, startIndex, chunk, 0, chunk.Length);
fileChunks.Add(chunk);
}
}
Код ViewModel
public UploadViewModel()
{
uploadModel = new UploadModel(); // important – must initialize model
OpenFileCommand = new RelayCommand(OpenDialog);
StatusText = "Please select a file to upload";
context.UploadFileCompleted = new EventHandler<AsyncCompletedEventArgs>(context_UploadFileCompleted);
}
private void OpenDialog()
{
OpenFileDialog ofd = new OpenFileDialog();
if ((bool)ofd.ShowDialog())
{
_fileName = ofd.File.Name;
FileStream fs = ofd.File.OpenRead();
fileSize = (double)fs.Length;
index = 0;
sendData = 0;
byte[] file = new byte[fs.Length];
fs.Read(file, 0, file.Length);
// call our model and convert file into chunks
uploadModel.convertToChunks(file);
// start upload process, this only sends the first chunk all subsquent chunks
// are sent on the context_UploadFileToCrmCompleted function
uploadModel.uploadChunks(index, _fileName);
}
}
void context_UploadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error == null)
{
sendData = uploadModel.fileChunks[index].Length;
TotalFileSize = byteTranslation(sendData) "/" byteTranslation(fileSize);
if ((index 1) < uploadModel.fileChunks.Count)
{
this.CurrentProgress = index / uploadModel.fileChunks.Count;
index = 1;
uploadModel.uploadChunks(index, _fileName);
}
else
{
StatusText = "Successfully uploaded. Submitting to the file repository...";
// Submit the upload to SharePoint
}
}
}
Комментарии:
1. И просто обновление. Если я перемещу фрагменты загрузки из модели в viewmodel, все будет запущено правильно. Что должно произойти, чтобы это сработало в модели? Спасибо.
Ответ №1:
Надеюсь, я ничего не упустил… у вас есть два FileUploadServiceSoapClients?
Один в ViewModel и один в модели. Вы вызываете службу в модели, но завершенный обработчик присваивается контексту ViewModel.
Итак, вы должны написать
uploadModel.context.UploadFileCompleted = new EventHandler<AsyncCompletedEventArgs>(context_UploadFileCompleted);
вместо
context.UploadFileCompleted = new EventHandler<AsyncCompletedEventArgs>(context_UploadFileCompleted);
Вероятно, вам лучше не использовать ServiceClient непосредственно в ViewModel, а передать обратный вызов или позволить модели вызвать собственное событие.