Здравствуйте! Сегодня: Вс, 22 Сен 2019, Ваш IP: 3.227.254.12 Войти через loginza
 
Вход | Регистрация | Забыли пароль?
Мой Kbyte.Ru
> Список форумов Kbyte.Ru - - Web-программирование
+ Создать новую тему Страница: 1
Тема: Асинхронная загрузка файлов на сервер · +  +  дата добавления: 21.09.2014 / 21:19
Автор темы:
servmv
servmv
тем: 4 / ответов: 14 / благодарностей: 0 / репутация: 0
ответов: 14
создал(а) тем: 4


Народ ознакомился со Статьей
оч. хорошая статья, но про MVC. Народ помогите с серверной частью на обычном Веб проекте. Если с простыми запросами все понятно, юзаю WebService.asmx, то вот с загрузкой файла не черта не понятно. Вот код скрипта:
<script type="text/javascript">
    $(document).ready(function () {
    $("#Button").click(function (evt) {
            var fileUpload = $("#FileUpload").get(0);
            var files = fileUpload.files;
            var data = new FormData();
            for (var i = 0; i < files.length; i++) {
                data.append(files[i].name, files[i]);}
            var options = {};
            options.url = "FileUploadHandler.ashx";
            options.type = "POST";
            options.data = data;
            options.contentType = false;
            options.processData = false;
            options.success = function (result) { alert(result); };
            options.error = function (err) { alert(err.statusText); };
            $.ajax(options);
            evt.preventDefault();
        });
    });
</script>


<form id="form1" runat="server">
    <div>
    <asp:FileUpload ID="FileUpload" runat="server" AllowMultiple="true" ClientIDMode="Static" />
<br />
<br />
<asp:Button ID="Button" runat="server" Text="Upload Selected File(s)"  ClientIDMode="Static" />
    </div>
    </form>


Сразу 2 вопроса, во первых странное ограничение на размер файлов, насколько я понял размеры файлов складываются и общий размер не какой, файл 90 мегабайт (один) не запихать.

секция в конфиг

<httpRuntime maxRequestLength="2147483647" /> ограничена размерностью INT32

далее самое важное

асинхронный прием файлов и индикацией процесса загрузки.
народ объясните хотя бы на пальцах куда пихать файл? я пытаюсь в FileUploadHandler.ashx обработчик. но опять же, надо это как то отдельным потоком пустить, из которого извлекать данные о процессе. Взрыв мозга помогите....
Технологии: ASP .NET, JavaScript, jQuery
 
Ответ # 1 # · +  +  дата добавления: 23.09.2014 / 10:18
Автор ответа:
Алексей Немиро
Алексей Немиро
тем: 534 / ответов: 5130 / благодарностей: 325 / репутация: 211
Чашка Kbyte.Ru>>
Url: aleksey.nemiro.ru
Icq: 261779681
Skype: alekseynemiro
ответов: 5130
создал(а) тем: 534


Информация о состоянии загрузки обновляется в Session.
Session["BytesReceived"] += число загруженных байт

В обработчиках (ashx) просто так доступа к Session нет и работать она не будет. Нужно реализовать в классе System.Web.SessionState.IRequiresSessionState.

public class MyHandler : IHttpHandler, System.Web.SessionState.IRequiresSessionState

В моем примере, потоки нужны только для локального тестирования, там делается искусственная пауза, чтобы было видно, что все работает.

Должно быть два обработчика: первый принимает файл, обновляя статус загрузки в Session; второй - возвращает информацию о состоянии загрузки из Session.

Это как в супермаркете, кассир принимает товары у покупателя, а кассовый аппарат считает стоимость. Нужен кассир и кассовый аппарат :)
 
Ответ # 2 # · +  +  дата добавления: 23.09.2014 / 10:34
Автор ответа:
Алексей Немиро
Алексей Немиро
тем: 534 / ответов: 5130 / благодарностей: 325 / репутация: 211
Чашка Kbyte.Ru>>
Url: aleksey.nemiro.ru
Icq: 261779681
Skype: alekseynemiro
ответов: 5130
создал(а) тем: 534


PS: Статья уже старая, два года прошло, сейчас HTML5 достаточно хорошо поддерживается браузерами. В HTML5 это сделать проще.

Код примерно такой:
<input type="file" name="files" id="files" multiple="true" />
if(window.FileReader == null) 
{
  alert("К сожалению, ваш браузер не поддерживает HTML5 или функции загрузки файлов. Пожалуйста, убедитесь, что вы используете последнюю версию браузера, либо воспользуйтесь другим браузером, поддерживающим HTML5: Chrome, Safari, FireFox, Opera, IE10/11.");
  return;
}
// цепляем обработчик изменения в элементе files (см. первый блок кода)
$("#files").bind({ change: function() { UploadFiles(this.files); } });
// функция отправки файлов на сервер
function UploadFiles(files) {
  $.each(files, function(i, file) {
    alert(file.name);
    var reader = new FileReader();
    reader.onload = (function () {
      var data = new FormData();
      data.append("file", file); // файл передается на сервер в параметр file

      $.ajax({
        url: "/Upload.aspx", // страница, которая будет принимать файл в параметре file
        enctype: "multipart/form-data", // вжно
        type: "POST",
        xhr: function () {
          var myXhr = $.ajaxSettings.xhr();
          if (myXhr.upload) {
            myXhr.upload.addEventListener("progress", function (e) {
              if (e.lengthComputable) {
                alert(Math.round((e.loaded * 100) / e.total) + "%"); // конечно, alert лучше не использовать :)
              }
            }, false);
          }
          return myXhr;
        },
        beforeSend: function () { alert("Отправка файла..."); },
        success: function (result) {
          // код обработки ответа сервера, ответ может быть в json
        },
        error: function(e, status, message){
          alert("К сожалению, при загрузке файла произошла ошибка: HTTP " + status + " / " + message + ".");
        },
        data: data,
        cache: false,
        contentType: false,
        processData: false
      });
    });

    // непосредственно отправка файла на сервер
    reader.readAsArrayBuffer(file); 
  }
}
(это все JavaScript)

jQuery должен быть достаточно свежим, у меня этот код работает с jQuery 1.7.2. С более старыми версиями, если не изменяет память, были какие-то проблемы с отправкой файлов на сервер.
 
Ответ # 3 # · +  +  дата добавления: 25.09.2014 / 15:53
Автор ответа:
servmv
servmv
тем: 4 / ответов: 14 / благодарностей: 0 / репутация: 0
ответов: 14
создал(а) тем: 4


Эмм.. спасибо за скрипты предложенные, чють позже разберусь, я может не верно выразился, вопрос был по серверной части.
я тут немного приболел грипом, мозги в обще не работали, но я снова тут.
и так алгоритм серверной части в моем понимании, и уже часть кода написана:

upload.ashx:
If (context.Request.Files.Count > 0) Then ' если есть файлы (со стороны клиента все отработало верно)
    Dim t As Thread = New Thread(AddressOf ThreadUpload) ' запускаем процедуру загрузки файлов в отдельном потоке.
    t.IsBackground = True
    t.Start({context.Session, context.Request.Files})
    context.Response.ContentType = "text/plain" ' Возвращаем клиенту сообщение и выходим (получается загрузка файлов идет в отдельном потоке, и это работает)
    context.Response.Write("Начата загрузка файлов!")
Else
    context.Response.ContentType = "text/plain"
    context.Response.Write("Привышен максимальный размер файлов!")
End If
далее..
Private Sub ThreadUpload(ByVal args As Object)
   Dim session As HttpSessionStateBase = args.GetValue(0) ' извлекаем аргументы
   Dim files As HttpFileCollection = args.GetValue(1)
   For F = 0 To files.Count - 1 ' цыкл, по очереди принимаем файлы
       Dim file As HttpPostedFile = files(F)
       Dim DI As DirectoryInfo = New DirectoryInfo("D:\Документы\Visual Studio 2010\Projects\TestUpload\TestUpload\uploads")
       Dim fs As FileStream = New FileStream(Path.Combine(DI.FullName, file.FileName), FileMode.Create, FileAccess.Write, FileShare.ReadWrite)
       Using (fs)
           Dim br As BinaryWriter = New BinaryWriter(fs, Encoding.UTF8)
           Using br
              ' Вот тут вопрос по InputStream.Read по сути прием завершится когда file.InputStream.Read вернет 0,
              ' мну тут сразу мысли в голову, а если с нетом проблемы? причем в статье запись файла также производят напрямую br.Write(buffer, 0, readBytes)
              ' ну прервался инет ... и недописанный файл на диске? но в принципе проблема решаемая))  
              ' далее... прерывание может быть "коротким" достаточным чтобы выбить из цыкла While но по факту не существенное. 
              ' короче вопрос,  подскажите как работать с InputStream.ReadTimeout данный таймаут обновляется? при чтение потока (file.InputStream.Read)? или относится
              ' ко всему потоку? и как отловить событие превышения таймаута?
              Dim buffer(4095) As Byte
              Dim readBytes As Integer = 1
              While (readBytes) > 0
                 readBytes = file.InputStream.Read(buffer, 0, buffer.Length)
                 br.Write(buffer, 0, readBytes)
              End While
            End Using
       End Using
   Next
End Sub
 
Ответ # 4 # · +  +  дата добавления: 25.09.2014 / 17:36
Автор ответа:
Алексей Немиро
Алексей Немиро
тем: 534 / ответов: 5130 / благодарностей: 325 / репутация: 211
Чашка Kbyte.Ru>>
Url: aleksey.nemiro.ru
Icq: 261779681
Skype: alekseynemiro
ответов: 5130
создал(а) тем: 534


При использовании HTML5 ничего особо в серверной части делать не нужно.
Просто сохранять файл обычным способом, как без использования JavaScript.

Потоки вообще не нужны, я их использовал чтобы сделать искусственную паузу, т.к. в localhost загрузка происходит мгновенно и progress не успевает отобразить изменения.

При использовании потоков и возможностей HTML5, скорее всего работать все будет неправильно.

Файл можно сохранить сразу, целиком, а не кусками. Сохранять кусками имеет смысл, если объем будет исчисляться гигабайтами.

Во втором ответе, есть обработчик события progress, информация в нем берется из браузера, не нужно делать никаких сессий и потоков, все уже и так сделано. Браузер сам будет отправлять данные в потоках, если решит, что следует делать именно так.

Во втором ответе также есть обработчик ошибок на стороне клиента, если сервер выдаст код, отличный от 2xx.

В общем ничего особого на сервере делать не нужно. Главное правильный клиентский код написать.
короче вопрос, подскажите как работать с InputStream.ReadTimeout данный таймаут обновляется? при чтение потока (file.InputStream.Read)? или относится
ко всему потоку? и как отловить событие превышения таймаута?
Относится ко всему потоку чтения При условии, что CanTimeout = True, но обычно оно всегда False, т.е. не поддерживается файловыми потоками.
 
Ответ # 5 # · +  +  дата добавления: 25.09.2014 / 17:44
Автор ответа:
Алексей Немиро
Алексей Немиро
тем: 534 / ответов: 5130 / благодарностей: 325 / репутация: 211
Чашка Kbyte.Ru>>
Url: aleksey.nemiro.ru
Icq: 261779681
Skype: alekseynemiro
ответов: 5130
создал(а) тем: 534


Что касается сохранения, то можно так:
file.SaveAs("путь и имя файла")
 
Ответ # 6 # · +  +  дата добавления: 01.10.2014 / 11:37
Автор ответа:
servmv
servmv
тем: 4 / ответов: 14 / благодарностей: 0 / репутация: 0
ответов: 14
создал(а) тем: 4


Продолжаем тему)
по поводу скрипта, во 2ром ответе.
Я общаюсь с javascript на "ВЫ", далеко не все понимаю что там написано, но при простом копировании текста выдает ошибку, что-то с последними скобками не то, но браузер отказывается выполнять скрипт аргументируя что мол функция не найдена, юзаю лису пробовал и оперу и IE.

давай напишу что сделал со стороны сервера:
Предполагается что пользователь грузит много фото:
session("FilesCount") = files.Count ' число загружаемых файлов
session("FileCurent") = F ' F-это текущий загружаемый файл по счету от 1 до files.Count
session("BytesReceived") += readBytes ' число уже загруженных байт для файла с номером F

народ помогите со скриптом (подробно, чтобы понять как это работает)

сейчас юзаю вот это:
function UploadFiles() 
{
    var fileUpload = document.getElementById("Files");
	var files = fileUpload.files;
	var data = new FormData();
	for (var i = 0; i < files.length; i++) {
	data.append(files[i].name, files[i]);}
	var options = {};
	options.url = "/service/upload.ashx";
	options.type = "POST";
	options.enctype = "multipart/form-data", // вжно
	options.data = data;
	options.contentType = false;
	options.processData = false;
	options.success = function (result) { UploadResult(result); };
	options.error = function (err) { UploadErr(err.statusText); };
	$.ajax(options);
	evt.preventDefault();
}

function UploadResult(result) 
{
    alert(result); // ну вынес пока для наглядности
}
function UploadErr(result) {
    alert(result);
}

<div class="Information">
<table><tr><td valign="top">
<div class="fileUpload button" >
<span>Выбрать</span>
<input id="Files" type="file" class="upload" Multiple="true" onselect="" accept="images/*" />
</div>
</td><td>
<a href="#" class="button" onclick="javascript: UploadFiles()">Загрузить</a>
</td></tr></table>
</div>
Технологии: ActionScript, ASP, ASP .NET
 
Ответ # 7 # · +  +  дата добавления: 01.10.2014 / 12:11
Автор ответа:
servmv
servmv
тем: 4 / ответов: 14 / благодарностей: 0 / репутация: 0
ответов: 14
создал(а) тем: 4


Еще момент: чтобы понятно было у меня 2 сервера, 1вый это сайт 2рой файловый с которым я вас сейчас и мучаю.
Принцип такой, на сайте происходит загрузка страницы, в iframe грузится страница из файлового сервер запрошенная с get ключом, по этому ключу сервер делает короткий запрос на сайт и получает в ответ все данные необходимые файловому серверу (ключ временный), далее при загрузке файлов:
если ProcessRequest верно распознал пользователя, и есть файлы, возвращает "Начата загрузка файлов!" и далее работает только ThreadUpload обновляя
данные сесии.
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        If (context.Request.Files.Count > 0) Then ' если есть файлы
            Dim Code As String = context.Session("Key") ' если в сесии есть код
            If Not Code Is Nothing Then
                Dim N = Sessions.GetN(Code) ' найдем данные сесии
                If N > -1 Then
                    Dim t As Thread = New Thread(AddressOf ThreadUpload) ' открываем новый поток на загрузку файлов
                    t.IsBackground = True
                    t.Start({context.Session, context.Request.Files})
                    context.Response.ContentType = "text/plain"
                    context.Response.Write("Начата загрузка файлов!")
                Else
                    context.Response.ContentType = "text/plain"
                    context.Response.Write("Невозможно определить пользователя!")
                End If
            Else
                context.Response.ContentType = "text/plain"
                context.Response.Write("Ошибка сесии!")
            End If
        Else
            context.Response.ContentType = "text/plain"
            context.Response.Write("Пустой запрос!")
        End If
    End Sub
 
Ответ # 8 # · +  +  дата добавления: 01.10.2014 / 13:29
Автор ответа:
Алексей Немиро
Алексей Немиро
тем: 534 / ответов: 5130 / благодарностей: 325 / репутация: 211
Чашка Kbyte.Ru>>
Url: aleksey.nemiro.ru
Icq: 261779681
Skype: alekseynemiro
ответов: 5130
создал(а) тем: 534


Я общаюсь с javascript на "ВЫ", далеко не все понимаю что там написано, но при простом копировании текста выдает ошибку, что-то с последними скобками не то, но браузер отказывается выполнять скрипт аргументируя что мол функция не найдена, юзаю лису пробовал и оперу и IE.
Да, есть такое. Поправил. Также добавил обработчик события, который инициирует отправку файла на сервер сразу после выбора.

      <input type="file" name="files" id="files" multiple="true" />
      <br />
      <!--input type="button" value="Отправить" onclick="UploadFiles($('#files').prop('files'));" /-->
      <hr />
      <div id="status"></div>

      <script type="text/javascript">
        $(document).ready(function(){
          if(window.FileReader == null) 
          {
            alert("К сожалению, ваш браузер не поддерживает HTML5 или функции загрузки файлов. Пожалуйста, убедитесь, что вы используете последнюю версию браузера, либо воспользуйтесь другим браузером, поддерживающим HTML5: Chrome, Safari, FireFox, Opera, IE10/11.");
            return;
          }

          // целяем обработчик события, который будет срабатывать сразу при выборе файлов
          $("#files").bind({ change: function () { UploadFiles(this.files); } });
        });

        // функция отправки файлов на сервер
        function UploadFiles(files) {
          // очищаем блок вывода статуса
          $('#status').empty(); 
          // перебираем выбранные файлы
          $.each(files, function (i, file) {
            // добавляем файл в блок статуса
            // процен загрузки будет отображаться в span
            var fileStatus = $('<div>Файл: <strong>' + file.name + '</strong> <span class="progress">0%</span></div>').appendTo('#status');
            // создаем читатель файлов
            var reader = new FileReader();
            // привязываем обработчик отправки файла
            reader.onload = (function () {
              // создаем форму, которая будет отправлена на сервер (т.к. файл нужно отправлять методом POST)
              var data = new FormData();
              // передаем в параметр file, файл, который нужно отправить на сервер (file - это переменная из цикла, см. 35 строку)
              data.append("file", file);
              // метод отправки файла при помощи jQuery
              $.ajax({
                url: "/Upload.aspx",            // страница, которая будет принимать файл в параметре file
                enctype: "multipart/form-data", // важно правильно указать тип содержимого
                type: "POST",                   // файлы отправляются только методом POST
                xhr: function () {
                  var myXhr = $.ajaxSettings.xhr();
                  if (myXhr.upload) {
                    // добавляем обработчик отправки данных
                    myXhr.upload.addEventListener("progress", function (e) {
                      if (e.lengthComputable) {
                        // меняем в статусе информацию о состоянии отправки файла на сервер
                        $('.progress', fileStatus).html(Math.round((e.loaded * 100) / e.total) + '%');
                      }
                    }, false);
                  }
                  return myXhr;
                },
                beforeSend: function () {
                  // здесь можно написать код, который будет вызываться перед отправкой файла на сервер
                  //alert("Отправка файла..."); 
                },
                success: function (result) {
                  // код обработки результата загрузки файла
                  alert(file.name + ' обработан: ' + result);
                },
                error: function (e, status, message) {
                  alert("К сожалению, при загрузке файла произошла ошибка: HTTP " + status + " / " + message + ".");
                },
                data: data,         // данные формы
                cache: false,       // кэширование нужно отключить
                contentType: false, // чтобы не было проблем с multipart/form-data
                processData: false  // хз, что это :)
              });
            });

            // запуск процедуры отправки файла на сервер
            reader.readAsArrayBuffer(file);
          });
        }
      </script>

Еще момент: чтобы понятно было у меня 2 сервера, 1вый это сайт 2рой файловый с которым я вас сейчас и мучаю.
Я обычно отправляю файл текущему серверу, а тот отправляет его второму.
Можно помучиться с кросс-доменной отправкой файлов со стороны клиента (не факт, что все получится и везде будет работать), но отправлять с сервера проще и надежней.

В целом, в моей статье показан совершенно другой метод отправки файлов. В коде, указанном в этой теме используется HTML5. Смешивать их не имеет смысла, да и проблем будет много. Для начала нужно определиться, какой метод использовать. В плане клиентского код, метод без HTML5 (с фреймом, как в статье), более простой, клиентского кода меньше и меньше подводных камней.
 
Ответ # 9 # · +  +  дата добавления: 01.10.2014 / 21:05
Автор ответа:
servmv
servmv
тем: 4 / ответов: 14 / благодарностей: 0 / репутация: 0
ответов: 14
создал(а) тем: 4



Я обычно отправляю файл текущему серверу, а тот отправляет его второму.
Мысль интересная конечно. Но мне кажется при большом движении контента будет большая нагрузка на первый сервер.
короче дописал я это дело не дождавшись ответа xD
весь код кидать не буду, может оформлю отдельным демо проектом но позже.
Суть такова: 2 обработчика (по факту 3, но третий для связи с первым сервером)
и так первый: .ashx принимает информацию о файлах и передает в отдельный поток - процедуру на скачивания возвращает "upload"
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        If (context.Request.Files.Count > 0) Then ' если есть файлы
           ' ........
           Dim t As Thread = New Thread(AddressOf ThreadUpload) ' открываем новый поток на загрузку файлов
           t.IsBackground = True
           t.Start({context.Session, context.Request.Files})
           context.Response.ContentType = "text/plain"
           context.Response.Write("upload")
          ' ........

далее отрабатывает скрипт, я написал вот это(код полностью):

function SelectedFiles() // при выборе файлов
{
    var elm_s = document.getElementById("bSelected"); // гасим кнопку выбора файлов
    elm_s.style.display = "none";// гасим кнопку "выбрать файл"
    document.getElementById('progress').style.width = 0;// обнуляем прогресс бар
    UploadFiles() // запуск загрузки
}

function UploadFiles() 
{
    var fileUpload = document.getElementById("Files");
	var files = fileUpload.files;
	var data = new FormData();
	for (var i = 0; i < files.length; i++) {
	data.append(files[i].name, files[i]);}
	var options = {};
	options.url = "/service/upload.ashx";
	options.type = "POST";
	options.enctype = "multipart/form-data", // вжно
	options.data = data;
	options.contentType = false;
	options.max_file_size = "1024mb"
	options.processData = false;
	options.success = function (result) { UploadResult(result); };
	options.error = function (err) { UploadErr(err.statusText); };
	var interest = document.getElementById('interest');
	var mess = document.getElementById('mess');
	mess.style.display = "block";
	interest.innerHTML = 'Подготовка файлов, ждите...'; // следующая строка вызывает "подвисание", типо не чего не происходит, 
                                                            // если файлов много это напрягает, потому решил вывести эту фразу
	$.ajax(options);
	evt.preventDefault();
}

function UploadResult(result) {
    var mess = document.getElementById('interest');
    if (result == "upload")// то что нам вернул сервер
    {
        mess.innerHTML = 'Начата загрузка файлов!';
        setTimeout(Update, 1000); // запускаем слежение за загрузкой
    }
    if (result == "err") {
        mess.innerHTML = 'Ошибка загрузки файлов!';
        var elm_s = document.getElementById("bSelected"); // высвечиваем кнопку выбора файлов
        elm_s.style.display = "block";
    }
}
function UploadErr(result) {
    var interest = document.getElementById('interest');
    interest.innerHTML = 'Ошибка загрузки файлов!';
    var elm_s = document.getElementById("bSelected"); // высвечиваем кнопку выбора файлов
    elm_s.style.display = "block";
}

function Update() {
    id = document.getElementById("lSessionID").value;// тут на странице лежит некий ID, привязка, т.к. в .asmx(2рой обработчик) я не понял как достучатся до сесии.
    server.uploaddata.GetData(id, OnCompleteData) // вызываем сервер (2рой) обработчик, который нам и сообщит о процессе загрузки.
    
}
//  result[0] - число загружаемых файлов
//  result[1] - текущий загружаемый файл
//  result[2] - процент загрузки текущего файла (0-100)
//  result[3] - процент загрузки всех файлов (0-100)
function OnCompleteData(result) {
    var interest = document.getElementById('interest');
    var mess = document.getElementById('mess');
    if (result[0] == result[1]) 
    {
        if (result[2] == 100) 
        {
            var elm_s = document.getElementById("bSelected"); // высвечиваем кнопку выбора файлов
            elm_s.style.display = "block";
            interest.innerHTML = '';
            mess.style.display = "none";
        }
        else {
            interest.innerHTML = 'Загрузка файла ' + result[1] + ' из ' + result[0] + ', готово: ' + result[3] + '%';
            setTimeout(Update, 100);
            prog(result[3]);
        }
    }
    else {
        interest.innerHTML = 'Загрузка файла ' + result[1] + ' из ' + result[0] + ', готово: ' + result[3] + '%';
        setTimeout(Update, 100);
        prog(result[3]);
    }

}

function prog(interest) {
    document.getElementById('progress').style.width = interest * 3 + 'px';
}

ну и сам обработчик .asmx (тут надо представить в голове)
есть структура
Public Structure UploadFileDeclare
        Sub New(ByVal _FileName As String, ByVal _FileType As String, _
                ByVal _FileLength As UInt32)
            FileName = _FileName
            FileType = _FileType
            FileLength = _FileLength
            FileComment = ""
            BytesReceived = 0
            FileUploded = False
        End Sub
        ''' <summary>Имя загружаемого файла</summary>
        Public FileName As String
        ''' <summary>Описание файла</summary>
        Public FileComment As String
        ''' <summary>Тип файла, Video, Audio, Foto</summary>
        Public FileType As String
        ''' <summary>Длина файла в байтах</summary>
        Public FileLength As UInt32
        ''' <summary>Число принятых байт</summary>
        Public BytesReceived As UInt32
        ''' <summary>Флаг False - если еще грузится, True - уже загружен</summary>
        Public FileUploded As Boolean
    End Structure

Public Structure SessDeclare
   ''' <summary>Список загружаемых файлов</summary>
   Public FileLoad As List(Of UploadFileDeclare)
   Public FileCount As Integer
   Public SessionID As String
   Public UserID As String
   Public KeyID As String
End Structure

на первом этапе создается переменная, если еще не создана на базе структуры, данные в которую получает 2рой сервер от первого
при этом FileCount и FileLoad пустые
когда юзер загружает файлы первый обработчик заполняет FileCount (число файлов) сразу и с началом получения каждого файла добавляет FileLoad.add ... после чего в процессе обновляет BytesReceived в FileLoad(N), тоесть работает это все автономно а вот asmx уже извлекает эти данные.


<WebMethod()> _
    Public Function GetData(ByVal SessionID As String) As String()
        Dim ret() As String = {"0", "0", "0", "0"}
        If Not SessionID Is Nothing Then
            Dim N As Integer = Sessions.GetN(SessionID) ' получаем номер сесии по ключу
            If N > -1 Then
                If Sessions.Sess(N).UserID.Length = 20 Then
                    Dim FileCount As Integer = Sessions.Sess(N).FileCount ' число загружаемых файлов
                    ret(0) = FileCount.ToString
                    If FileCount > 0 Then
                        Dim FileUpload As Integer = Sessions.Sess(N).FileLoad.Count ' текущий загружаемый файл
                        ret(1) = FileUpload.ToString
                        Dim FilePercent As Integer = Sessions.Sess(N).FileLoad(FileUpload - 1).BytesReceived / (Sessions.Sess(N).FileLoad(FileUpload - 1).FileLength / 100)
                        ret(2) = FilePercent.ToString
                        Dim FileAllPercent As Integer = FileUpload / (FileCount / 100)
                        ret(3) = FileAllPercent
                    End If

                End If
            End If
        End If
        Return ret
    End Function



пло.. 2 недели головной боли

народ на всякий случай, чтобы мне потом не говорили мол я это украл с kbyte.ru, автор кода Митько Виталий Сергеевич
 
Ответ # 10 # · +  +  дата добавления: 01.10.2014 / 21:55
Автор ответа:
servmv
servmv
тем: 4 / ответов: 14 / благодарностей: 0 / репутация: 0
ответов: 14
создал(а) тем: 4


По пробовал код предложенный вами не хочет работать. Не пойму какая точка входа должна быть, я прописал временный "service/Handler.ashx" поставил точку остановки на IF
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
   If (context.Request.Files.Count > 0) Then ' если есть файлы

   End If
End Sub
и нечего не происходит, со стороны браузера ошибка "К сожалению, при загрузке файла произошла ошибка: HTTP error / ."
причем есть еще не приятный момент сколько файлов столько и окон с ошибками, + насколько я понял файлы передаются все одновременно, что не есть гуд.
 
Ответ # 11 # · +  +  дата добавления: 01.10.2014 / 23:03
Автор ответа:
Алексей Немиро
Алексей Немиро
тем: 534 / ответов: 5130 / благодарностей: 325 / репутация: 211
Чашка Kbyte.Ru>>
Url: aleksey.nemiro.ru
Icq: 261779681
Skype: alekseynemiro
ответов: 5130
создал(а) тем: 534


Нужно смотреть, что отвечает сервер. В браузер типа Chrome есть возможность посмотреть подробный ответ сервера. Либо через Fiddler.

Файлы отправляются по одному, но в несколько потоков. Один запрос - один файл.
Можно отправлять последовательно, но это все JavaScript-ом придется делать.

Нужно будет еще одну статю написать на эту тему, если будет время.
 
Ответ # 12 # · +  +  дата добавления: 04.10.2014 / 17:48
Автор ответа:
servmv
servmv
тем: 4 / ответов: 14 / благодарностей: 0 / репутация: 0
ответов: 14
создал(а) тем: 4


Нада, надо. Очень скудно информации в нете, только надо писать о WebForm, MVC не все юзают, или на обе темы, только не смешивая (2 статьи)
 
Страница: 1 + Создать новую тему