/// <summary> /// 文本处理(直接传入文本内容) /// </summary> /// <param name="fop">文本处理命令</param> /// <param name="text">文本内容</param> /// <returns></returns> public HttpResult DfopText(string fop, string text) { HttpResult result = new HttpResult(); string scheme = this.config.UseHttps ? "https://" : "http://"; string dfopUrl = string.Format("{0}{1}/dfop?fop={2}", scheme, Config.DefaultApiHost, fop); string token = auth.CreateManageToken(dfopUrl); string boundary = HttpManager.CreateFormDataBoundary(); string sep = "--" + boundary; StringBuilder sb = new StringBuilder(); sb.AppendLine(sep); sb.AppendFormat("Content-Type: {0}", ContentType.TEXT_PLAIN); sb.AppendLine(); sb.AppendLine("Content-Disposition: form-data; name=data; filename=text"); sb.AppendLine(); sb.AppendLine(text); sb.AppendLine(sep + "--"); byte[] data = Encoding.UTF8.GetBytes(sb.ToString()); result = httpManager.PostMultipart(dfopUrl, data, boundary, token, true); return(result); }
/// <summary> /// 如果uri是本地文件路径则使用此方法 /// </summary> /// <param name="fop">文件处理命令</param> /// <param name="localFile">文件名</param> /// <returns>处理结果</returns> public HttpResult DfopData(string fop, string localFile) { HttpResult result = new HttpResult(); try { string scheme = this.config.UseHttps ? "https://" : "http://"; string dfopUrl = string.Format("{0}{1}/dfop?fop={2}", scheme, Config.DefaultApiHost, fop); string token = auth.CreateManageToken(dfopUrl); string boundary = HttpManager.CreateFormDataBoundary(); string sep = "--" + boundary; StringBuilder sbp1 = new StringBuilder(); sbp1.AppendLine(sep); string filename = Path.GetFileName(localFile); sbp1.AppendFormat("Content-Type: {0}", ContentType.APPLICATION_OCTET_STREAM); sbp1.AppendLine(); sbp1.AppendFormat("Content-Disposition: form-data; name=\"data\"; filename={0}", filename); sbp1.AppendLine(); sbp1.AppendLine(); StringBuilder sbp3 = new StringBuilder(); sbp3.AppendLine(); sbp3.AppendLine(sep + "--"); byte[] partData1 = Encoding.UTF8.GetBytes(sbp1.ToString()); byte[] partData2 = File.ReadAllBytes(localFile); byte[] partData3 = Encoding.UTF8.GetBytes(sbp3.ToString()); MemoryStream ms = new MemoryStream(); ms.Write(partData1, 0, partData1.Length); ms.Write(partData2, 0, partData2.Length); ms.Write(partData3, 0, partData3.Length); result = httpManager.PostMultipart(dfopUrl, ms.ToArray(), boundary, token, true); } catch (Exception ex) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("[{0}] [dfop] Error: ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")); Exception e = ex; while (e != null) { sb.Append(e.Message + " "); e = e.InnerException; } sb.AppendLine(); result.RefCode = (int)HttpCode.USER_UNDEF; result.RefText += sb.ToString(); } return(result); }
/// <summary> /// [异步async]文本处理(直接传入文本内容) /// </summary> /// <param name="fop">文本处理命令</param> /// <param name="text">文本内容</param> /// <returns></returns> public async Task <HttpResult> DfopTextAsync(string fop, string text) { HttpResult result = new HttpResult(); try { string dfopUrl = string.Format("{0}/dfop?fop={1}", Config.DFOP_API_HOST, fop); string token = auth.CreateManageToken(dfopUrl); string boundary = HttpManager.CreateFormDataBoundary(); string sep = "--" + boundary; StringBuilder sb = new StringBuilder(); sb.AppendLine(sep); sb.AppendFormat("Content-Type: {0}", ContentType.TEXT_PLAIN); sb.AppendLine(); sb.AppendLine("Content-Disposition: form-data; name=data; filename=text"); sb.AppendLine(); sb.AppendLine(text); sb.AppendLine(sep + "--"); byte[] data = Encoding.UTF8.GetBytes(sb.ToString()); result = await httpManager.PostMultipartAsync(dfopUrl, data, boundary, token, true); } catch (Exception ex) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("[{0}] dfop Error: ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")); Exception e = ex; while (e != null) { sb.Append(e.Message + " "); e = e.InnerException; } sb.AppendLine(); result.RefCode = (int)HttpCode.USER_EXCEPTION; result.RefText += sb.ToString(); } return(result); }
/// <summary> /// 如果处理内容是流则使用此方法 /// </summary> /// <param name="fop">文件处理命令</param> /// <param name="stream">数据流</param> /// <param name="mimeType">数据内容类型</param> /// <param name="fileName">文件名</param> /// <returns>处理结果</returns> public async Task <HttpResult> DfopStream(string fop, Stream stream, string mimeType, string fileName) { var result = new HttpResult(); try { var scheme = _config.UseHttps ? "https://" : "http://"; var dfopUrl = $"{scheme}{Config.DefaultApiHost}/dfop?fop={fop}"; var token = _auth.CreateManageToken(dfopUrl); var boundary = HttpManager.CreateFormDataBoundary(); var part = new StreamContent(stream); part.Headers.ContentType = MediaTypeHeaderValue.Parse(mimeType); var content = new MultipartFormDataContent(boundary) { { part, "data", fileName } }; result = await _httpManager.PostAsync(dfopUrl, content, token, true); } catch (Exception ex) { var sb = new StringBuilder(); sb.Append($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.ffff}] [dfop] Error: "); var e = ex; while (e != null) { sb.Append(e.Message + " "); e = e.InnerException; } sb.AppendLine(); result.RefCode = (int)HttpCode.USER_UNDEF; result.RefText += sb.ToString(); } return(result); }
/// <summary> /// 上传数据流 /// </summary> /// <param name="stream">(确定长度的)数据流</param> /// <param name="key">要保存的key</param> /// <param name="token">上传凭证</param> /// <param name="putExtra">上传可选设置</param> /// <returns>上传数据流后的返回结果</returns> public HttpResult UploadStream(Stream stream, string key, string token, PutExtra putExtra) { if (putExtra == null) { putExtra = new PutExtra(); } if (string.IsNullOrEmpty(putExtra.MimeType)) { putExtra.MimeType = "application/octet-stream"; } if (putExtra.ProgressHandler == null) { putExtra.ProgressHandler = DefaultUploadProgressHandler; } if (putExtra.UploadController == null) { putExtra.UploadController = DefaultUploadController; } string fname = key; if (string.IsNullOrEmpty(key)) { fname = "fname_temp"; } HttpResult result = new HttpResult(); try { string boundary = HttpManager.CreateFormDataBoundary(); StringBuilder bodyBuilder = new StringBuilder(); bodyBuilder.AppendLine("--" + boundary); if (key != null) { //write key when it is not null bodyBuilder.AppendLine("Content-Disposition: form-data; name=\"key\""); bodyBuilder.AppendLine(); bodyBuilder.AppendLine(key); bodyBuilder.AppendLine("--" + boundary); } //write token bodyBuilder.AppendLine("Content-Disposition: form-data; name=\"token\""); bodyBuilder.AppendLine(); bodyBuilder.AppendLine(token); bodyBuilder.AppendLine("--" + boundary); //write extra params if (putExtra.Params != null && putExtra.Params.Count > 0) { foreach (var p in putExtra.Params) { if (p.Key.StartsWith("x:")) { bodyBuilder.AppendFormat("Content-Disposition: form-data; name=\"{0}\"", p.Key); bodyBuilder.AppendLine(); bodyBuilder.AppendLine(); bodyBuilder.AppendLine(p.Value); bodyBuilder.AppendLine("--" + boundary); } } } //prepare data buffer int bufferSize = 1024 * 1024; byte[] buffer = new byte[bufferSize]; int bytesRead = 0; putExtra.ProgressHandler(0, stream.Length); MemoryStream dataMS = new MemoryStream(); while ((bytesRead = stream.Read(buffer, 0, bufferSize)) != 0) { dataMS.Write(buffer, 0, bytesRead); } //write crc32 uint crc32 = CRC32.CheckSumBytes(dataMS.ToArray()); //write key when it is not null bodyBuilder.AppendLine("Content-Disposition: form-data; name=\"crc32\""); bodyBuilder.AppendLine(); bodyBuilder.AppendLine(crc32.ToString()); bodyBuilder.AppendLine("--" + boundary); //write fname bodyBuilder.AppendFormat("Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"", fname); bodyBuilder.AppendLine(); //write mime type bodyBuilder.AppendFormat("Content-Type: {0}", putExtra.MimeType); bodyBuilder.AppendLine(); bodyBuilder.AppendLine(); //write file data StringBuilder bodyEnd = new StringBuilder(); bodyEnd.AppendLine(); bodyEnd.AppendLine("--" + boundary + "--"); byte[] partData1 = Encoding.UTF8.GetBytes(bodyBuilder.ToString()); byte[] partData2 = dataMS.ToArray(); byte[] partData3 = Encoding.UTF8.GetBytes(bodyEnd.ToString()); MemoryStream ms = new MemoryStream(); ms.Write(partData1, 0, partData1.Length); ms.Write(partData2, 0, partData2.Length); ms.Write(partData3, 0, partData3.Length); //get upload host string ak = UpToken.GetAccessKeyFromUpToken(token); string bucket = UpToken.GetBucketFromUpToken(token); if (ak == null || bucket == null) { return(HttpResult.InvalidToken); } string uploadHost = this.config.UpHost(ak, bucket); putExtra.ProgressHandler(stream.Length / 5, stream.Length); result = httpManager.PostMultipart(uploadHost, ms.ToArray(), boundary, null); putExtra.ProgressHandler(stream.Length, stream.Length); if (result.Code == (int)HttpCode.OK) { result.RefText += string.Format("[{0}] [FormUpload] Uploaded: #STREAM# ==> \"{1}\"\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"), key); } else { result.RefText += string.Format("[{0}] [FormUpload] Failed: code = {1}, text = {2}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"), result.Code, result.Text); } //close memory stream ms.Close(); dataMS.Close(); } catch (Exception ex) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("[{0}] [FormUpload] Error: ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")); Exception e = ex; while (e != null) { sb.Append(e.Message + " "); e = e.InnerException; } sb.AppendLine(); if (ex is QiniuException) { QiniuException qex = (QiniuException)ex; result.Code = qex.HttpResult.Code; result.RefCode = qex.HttpResult.Code; result.Text = qex.HttpResult.Text; result.RefText += sb.ToString(); } else { result.RefCode = (int)HttpCode.USER_UNDEF; result.RefText += sb.ToString(); } } finally { if (stream != null) { try { stream.Close(); stream.Dispose(); } catch (Exception) { } } } return(result); }
/// <summary> /// 上传数据 /// </summary> /// <param name="data">待上传的数据</param> /// <param name="key">可选,要保存的key</param> /// <param name="extra">可选,上传可选设置</param> /// <returns>上传数据后的返回结果</returns> private HttpResult UploadData(byte[] data, string token, string uploadUrl, string key = null, PutExtra putExtra = null) { if (putExtra == null) { putExtra = new PutExtra(); } string filename = key; if (string.IsNullOrEmpty(key)) { filename = "uploading.tmp"; } string boundary = HttpManager.CreateFormDataBoundary(); StringBuilder bodyBuilder = new StringBuilder(); bodyBuilder.Append("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"token\"\r\n\r\n" + token + "\r\n"); if (null != putExtra.Params && putExtra.Params.Count > 0) { foreach (KeyValuePair <string, string> p in putExtra.Params) { if (p.Key.StartsWith("x:")) { bodyBuilder.Append("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"" + p.Key + "\"\r\n\r\n" + p.Value + "\r\n"); } } } // write key if (null != key) { bodyBuilder.Append("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"key\"\r\n\r\n" + key + "\r\n"); } // write mime type if (!string.IsNullOrEmpty(putExtra.MimeType)) { bodyBuilder.Append("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"mimeType\"\r\n\r\n" + putExtra.MimeType + "\r\n"); } // write deadline if (-1 != putExtra.Deadline) { bodyBuilder.Append("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"deadline\"\r\n\r\n" + putExtra.Deadline.ToString() + "\r\n"); } // write filename bodyBuilder.Append("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"" + filename + "\"\r\nContent-Type: application/octet-stream\r\n\r\n"); // write file data StringBuilder bodyEnd = new StringBuilder(); bodyEnd.Append("\r\n--" + boundary + "--\r\n"); byte[] partHead = Encoding.UTF8.GetBytes(bodyBuilder.ToString()); byte[] partTail = Encoding.UTF8.GetBytes(bodyEnd.ToString()); // 允许空内容 int dataLength = 0; if (null != data) { dataLength = data.Length; } byte[] body = new byte[partHead.Length + dataLength + partTail.Length]; //Array.Copy(partHead, 0, body, 0, partHead.Length); // Buffer.BlockCopy 比 Array.Copy 简单,所以更快。 Buffer.BlockCopy(partHead, 0, body, 0, partHead.Length); if (null == data) { Buffer.BlockCopy(partTail, 0, body, partHead.Length, partTail.Length); } else { Buffer.BlockCopy(data, 0, body, partHead.Length, data.Length); Buffer.BlockCopy(partTail, 0, body, partHead.Length + data.Length, partTail.Length); } string url = uploadUrl + "/file/upload"; HttpResult result = httpManager.PostMultipart(url, body, boundary); return(result); }
/// <summary> /// 上传数据流 /// </summary> /// <param name="stream">(确定长度的)数据流</param> /// <param name="key">要保存的key</param> /// <param name="token">上传凭证</param> /// <param name="putExtra">上传可选设置</param> /// <returns>上传数据流后的返回结果</returns> public async Task <HttpResult> UploadStream(Stream stream, string key, string token, PutExtra putExtra) { if (putExtra == null) { putExtra = new PutExtra(); } if (string.IsNullOrEmpty(putExtra.MimeType)) { putExtra.MimeType = ContentType.APPLICATION_OCTET_STREAM; } if (putExtra.ProgressHandler == null) { putExtra.ProgressHandler = DefaultUploadProgressHandler; } if (putExtra.UploadController == null) { putExtra.UploadController = DefaultUploadController; } var fileName = key; if (string.IsNullOrEmpty(key)) { fileName = "fname_temp"; } var result = new HttpResult(); try { var boundary = HttpManager.CreateFormDataBoundary(); var content = new MultipartFormDataContent(boundary); var length = stream.Length; putExtra.ProgressHandler(0, length); // Key if (!string.IsNullOrEmpty(key)) { content.Add(new StringContent(key), "key"); } // Token content.Add(new StringContent(token), "token"); // Other params if (putExtra.Params != null) { foreach (var param in putExtra.Params) { content.Add(new StringContent(param.Value), param.Key); } } // Reuse stream if (!stream.CanSeek) { var ms = new MemoryStream((int)stream.Length); stream.CopyTo(ms); stream.Dispose(); stream = ms; } // CRC32 var crc32 = Crc32.CheckSumStream(stream); stream.Seek(0, SeekOrigin.Begin); content.Add(new StringContent(crc32.ToString()), "crc32"); // Primary content var part = new StreamContent(stream); part.Headers.ContentType = MediaTypeHeaderValue.Parse(putExtra.MimeType); content.Add(part, "file", fileName); // Get upload host var ak = UpToken.GetAccessKeyFromUpToken(token); var bucket = UpToken.GetBucketFromUpToken(token); if (ak == null || bucket == null) { return(HttpResult.InvalidToken); } var uploadHost = await _config.UpHost(ak, bucket); // TODO: Real progress putExtra.ProgressHandler(length / 5, length); result = await _httpManager.PostAsync(uploadHost, content, boundary); putExtra.ProgressHandler(length, length); if (result.Code == (int)HttpCode.OK) { result.RefText += $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.ffff}] [FormUpload] Uploaded: #STREAM# ==> \"{key}\"\n"; } else { result.RefText += $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.ffff}] [FormUpload] Failed: code = {result.Code}, text = {result.Text}\n"; } } catch (Exception ex) { var sb = new StringBuilder(); sb.Append($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.ffff}] [FormUpload] Error: "); var e = ex; while (e != null) { sb.Append(e.Message + " "); e = e.InnerException; } sb.AppendLine(); if (ex is QiniuException qex) { result.Code = qex.HttpResult.Code; result.RefCode = qex.HttpResult.Code; result.Text = qex.HttpResult.Text; result.RefText += sb.ToString(); } else { result.RefCode = (int)HttpCode.USER_UNDEF; result.RefText += sb.ToString(); } } return(result); }
/// <summary> /// [异步async]上传数据流 /// </summary> /// <param name="stream">数据流,流长度必须可确定</param> /// <param name="saveKey">要保存的key</param> /// <param name="token">上传凭证</param> /// <returns>数据流上传后的返回结果</returns> public async Task <HttpResult> UploadStreamAsync(Stream stream, string saveKey, string token) { HttpResult result = new HttpResult(); try { string boundary = HttpManager.CreateFormDataBoundary(); string sep = "--" + boundary; StringBuilder sbp1 = new StringBuilder(); sbp1.AppendLine(sep); sbp1.AppendLine("Content-Disposition: form-data; name=key"); sbp1.AppendLine(); sbp1.AppendLine(saveKey); sbp1.AppendLine(sep); sbp1.AppendLine("Content-Disposition: form-data; name=token"); sbp1.AppendLine(); sbp1.AppendLine(token); sbp1.AppendLine(sep); sbp1.AppendFormat("Content-Disposition: form-data; name=file; filename=\"{0}\"", saveKey); sbp1.AppendLine(); sbp1.AppendLine(); int bufferSize = 1024 * 1024; byte[] buffer = new byte[bufferSize]; int bytesRead = 0; MemoryStream dataMS = new MemoryStream(); while (true) { bytesRead = await stream.ReadAsync(buffer, 0, bufferSize); if (bytesRead == 0) { break; } await dataMS.WriteAsync(buffer, 0, bytesRead); } StringBuilder sbp3 = new StringBuilder(); sbp3.AppendLine(); sbp3.AppendLine(sep + "--"); byte[] partData1 = Encoding.UTF8.GetBytes(sbp1.ToString()); byte[] partData2 = dataMS.ToArray(); byte[] partData3 = Encoding.UTF8.GetBytes(sbp3.ToString()); MemoryStream ms = new MemoryStream(); await ms.WriteAsync(partData1, 0, partData1.Length); await ms.WriteAsync(partData2, 0, partData2.Length); await ms.WriteAsync(partData3, 0, partData3.Length); result = await httpManager.PostMultipartAsync(uploadHost, ms.ToArray(), boundary, null); result.RefText += string.Format("[{0}] [FormUpload] Uploaded: \"#STREAM#\" ==> \"{1}\"\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"), saveKey); } catch (Exception ex) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("[{0}] [FormUpload] Error: ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")); Exception e = ex; while (e != null) { sb.Append(e.Message + " "); e = e.InnerException; } sb.AppendLine(); result.RefCode = (int)HttpCode.USER_EXCEPTION; result.RefText += sb.ToString(); } return(result); }
/// <summary> /// [异步async]上传文件 - 可附加自定义参数 /// </summary> /// <param name="file">待上传的本地文件</param> /// <param name="saveKey">要保存的目标文件名称</param> /// <param name="token">上传凭证</param> /// <param name="extraParams">用户自定义的附加参数</param> /// <returns>上传文件后的返回结果</returns> public async Task <HttpResult> UploadFileAsync(StorageFile file, string saveKey, string token, Dictionary <string, string> extraParams) { HttpResult result = new HttpResult(); try { string boundary = HttpManager.CreateFormDataBoundary(); string sep = "--" + boundary; StringBuilder sbp1 = new StringBuilder(); sbp1.AppendLine(sep); sbp1.AppendLine("Content-Disposition: form-data; name=key"); sbp1.AppendLine(); sbp1.AppendLine(saveKey); sbp1.AppendLine(sep); sbp1.AppendLine("Content-Disposition: form-data; name=token"); sbp1.AppendLine(); sbp1.AppendLine(token); sbp1.AppendLine(sep); foreach (var d in extraParams) { sbp1.AppendFormat("Content-Disposition: form-data; name=\"{0}\"", d.Key); sbp1.AppendLine(); sbp1.AppendLine(); sbp1.AppendLine(d.Value); sbp1.AppendLine(sep); } sbp1.AppendFormat("Content-Disposition: form-data; name=file; filename=\"{0}\"", saveKey); sbp1.AppendLine(); sbp1.AppendLine(); StringBuilder sbp3 = new StringBuilder(); sbp3.AppendLine(); sbp3.AppendLine(sep + "--"); byte[] partData1 = Encoding.UTF8.GetBytes(sbp1.ToString()); byte[] partData2 = await ReadToByteArrayAsync(file); byte[] partData3 = Encoding.UTF8.GetBytes(sbp3.ToString()); MemoryStream ms = new MemoryStream(); await ms.WriteAsync(partData1, 0, partData1.Length); await ms.WriteAsync(partData2, 0, partData2.Length); await ms.WriteAsync(partData3, 0, partData3.Length); result = await httpManager.PostMultipartAsync(uploadHost, ms.ToArray(), boundary, null); result.RefText += string.Format("[{0}] [FormUpload] Uploaded: \"{1}\" ==> \"{2}\"\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"), file, saveKey); } catch (Exception ex) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("[{0}] [FormUpload] Error: ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")); Exception e = ex; while (e != null) { sb.Append(e.Message + " "); e = e.InnerException; } sb.AppendLine(); result.RefCode = (int)HttpCode.USER_EXCEPTION; result.RefText += sb.ToString(); } return(result); }
/// <summary> /// 上传文件 /// </summary> /// <param name="localFile">待上传的本地文件</param> /// <param name="saveKey">要保存的目标文件名称</param> /// <param name="token">上传凭证</param> /// <returns>上传文件后的返回结果</returns> public HttpResult UploadFile(string localFile, string saveKey, string token) { HttpResult result = new HttpResult(); try { string boundary = HttpManager.CreateFormDataBoundary(); StringBuilder sbp1 = new StringBuilder(); sbp1.AppendLine("--" + boundary); sbp1.AppendLine("Content-Disposition: form-data; name=key"); sbp1.AppendLine(); sbp1.AppendLine(saveKey); sbp1.AppendLine("--" + boundary); sbp1.AppendLine("Content-Disposition: form-data; name=token"); sbp1.AppendLine(); sbp1.AppendLine(token); sbp1.AppendLine("--" + boundary); sbp1.AppendFormat("Content-Disposition: form-data; name=file; filename=\"{0}\"", saveKey); sbp1.AppendLine(); sbp1.AppendLine(); StringBuilder sbp3 = new StringBuilder(); sbp3.AppendLine(); sbp3.AppendLine("--" + boundary + "--"); byte[] partData1 = Encoding.UTF8.GetBytes(sbp1.ToString()); byte[] partData2 = File.ReadAllBytes(localFile); byte[] partData3 = Encoding.UTF8.GetBytes(sbp3.ToString()); MemoryStream ms = new MemoryStream(); ms.Write(partData1, 0, partData1.Length); ms.Write(partData2, 0, partData2.Length); ms.Write(partData3, 0, partData3.Length); result = httpManager.PostMultipart(uploadHost, ms.ToArray(), boundary, null); if (result.Code == (int)HttpCode.OK) { result.RefText += string.Format("[{0}] [FormUpload] Uploaded: \"{1}\" ==> \"{2}\"\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"), localFile, saveKey); } else { result.RefText += string.Format("[{0}] [FormUpload] Failed: code = {1}, text = {2}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"), result.Code, result.Text); } } catch (Exception ex) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("[{0}] [FormUpload] Error: ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")); Exception e = ex; while (e != null) { sb.Append(e.Message + " "); e = e.InnerException; } sb.AppendLine(); result.RefCode = (int)HttpCode.USER_EXCEPTION; result.RefText += sb.ToString(); } return(result); }