public string Upload(string url, NameValueCollection formItems, NameValueCollection files) { int totalItems = 0; int itemsCompleted = 0; int formFieldsItems = 0; int fileFieldsItems = 0; int formFieldsCompleted = 0; int fileFieldsCompleted = 0; long totalFilesLength = this.getFilesLength(files); #region init variables // разделитель полей данных в POST запросе string boundary = "--xtr---" + DateTime.Now.Ticks.ToString("x"); // создаем запрос к переданному нам URL HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(url); httpRequest.ProtocolVersion = HttpVersion.Version11; httpRequest.Method = "POST"; // метод запроса - POST httpRequest.Timeout = this.Timeout; httpRequest.KeepAlive = true; // постоянное подключение //httpRequest.SendChunked = false; // Отправка данных кусками httpRequest.UserAgent = "xternalx uploader/0.1a"; // копирайт, хуле :) // указываем разделитель переданных параметров httpRequest.ContentType = "multipart/form-data; boundary=" + boundary; // получаем байты разделителя, для того, чтобы записать их в запрос к URL byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); httpRequest.ContentLength = this.calculateContentLength(boundary, formItems, files); //FileStream reqStream = new FileStream("D:\\stream.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.Read); Stream reqStream = httpRequest.GetRequestStream(); this.formEventArgs = new UploadFormProgressEventArgs(); this.filesEventArgs = new UploadFileProgressEventArgs(); #endregion #region form upload if (formItems != null && formItems.Count > 0) { formFieldsItems = formItems.Count; totalItems += formFieldsItems; // шаблон передаваемых строковых параметров "формы" // записываем переданные параметры "формы" в поток foreach (string key in formItems.Keys) { this.initFormUpload(key, formItems[key]); string formItem = this.formatFormUploadHeader(boundary, key, formItems[key]);// string.Format(formHeaderTemplate, key, formItems[key]); byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(formItem); reqStream.Write(formItemBytes, 0, formItemBytes.Length); this.updateFormUploadEvent(formItems[key].Length, formItems[key].Length, (float)((float)this.formEventArgs.CurrentBytesWritten / formItemBytes.Length) * 100); itemsCompleted++; formFieldsCompleted++; this.OnFormFieldUploadProgress(formEventArgs); } // дописали разделитель данных reqStream.Write(boundaryBytes, 0, boundaryBytes.Length); } else { // если список полей формы пуст, нужно дописать boundary reqStream.Write(boundaryBytes, 0, boundaryBytes.Length); } #endregion #region files upload if (files != null && files.Count > 0) { fileFieldsItems = files.Count; filesEventArgs.TotalFiles = fileFieldsItems; totalItems += fileFieldsItems; // шаблон для передаваемых файлов "формы" foreach (string formFieldName in files.Keys) { this.initFileUpload(files[formFieldName], formFieldName); string header = this.formatFileUploadHeader(formFieldName, Path.GetFileName(files[formFieldName]), this.getMimeType(files[formFieldName])); byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); reqStream.Write(headerbytes, 0, headerbytes.Length); FileStream fileStream = new FileStream(files[formFieldName], FileMode.Open, FileAccess.Read, FileShare.Read); this.filesEventArgs.FileSize = new FileInfo(files[formFieldName]).Length; byte[] buffer = new byte[this.BufferSize]; int bytesRead = 0; try { while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0) { reqStream.Write(buffer, 0, bytesRead); reqStream.Flush(); this.updateFileUploadEvent(bytesRead, bytesRead, fileFieldsCompleted); this.OnFileUploadProgress(filesEventArgs); } itemsCompleted++; fileFieldsCompleted++; filesEventArgs.UploadedFiles = fileFieldsCompleted; fileStream.Close(); reqStream.Write(boundaryBytes, 0, boundaryBytes.Length); } catch (WebException wex) { // При WebException возможно, что поток на запись будет разорван принудительно, // чтобы сделать возможным повторную отправку текущего файла, его нужно закрыть. fileStream.Close(); } } } #endregion reqStream.Close(); HttpWebResponse r = (HttpWebResponse)httpRequest.GetResponse(); StreamReader sr = new StreamReader(r.GetResponseStream()); return sr.ReadToEnd(); }
protected virtual void OnFileUploadProgress(UploadFileProgressEventArgs e) { if (UploadFileProgress != null) { UploadFileProgress(this, e); } }