场景描述:
特别声明
以下代码也是我从网络上复制的别人的,但是一开始跑我这边有点报错就稍微调整了一下。同时也是记录一下
服务端接口接受一个客户端上传的文件流后进行后续的业务操作。
客户端:
Modle类:
public class UploadParameterType { public UploadParameterType() { FileNameKey = "file"; Encoding = Encoding.UTF8; PostParameters = new Dictionary(); } /// /// 上传地址 /// public string Url { get; set; } ////// 文件名称key /// public string FileNameKey { get; set; } ////// 文件名称value /// public string FileNameValue { get; set; } ////// 编码格式 /// public Encoding Encoding { get; set; } ////// 上传文件的流 /// public Stream UploadStream { get; set; } ////// 上传文件 携带的参数集合 /// public IDictionaryPostParameters { get; set; } }
HTTP请求方法
public static string Execute(UploadParameterType parameter) { // 1.分界线 string boundary = string.Format("----{0}", DateTime.Now.Ticks.ToString("x")), // 分界线可以自定义参数 beginBoundary = string.Format("--{0}rn", boundary), endBoundary = string.Format("rn--{0}--rn", boundary); byte[] beginBoundaryBytes = parameter.Encoding.GetBytes(beginBoundary), endBoundaryBytes = parameter.Encoding.GetBytes(endBoundary); byte[] postBytes = new byte[] { }; using (MemoryStream memoryStream = new MemoryStream()) { // 2.组装开始分界线数据体 到内存流中 memoryStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length); // 3.组装 上传文件附加携带的参数 到内存流中 if (parameter.PostParameters != null && parameter.PostParameters.Count > 0) { foreach (KeyValuePairkeyValuePair in parameter.PostParameters) { string parameterHeaderTemplate = string.Format("Content-Disposition: form-data; name="{0}"rnrn{1}rn{2}", keyValuePair.Key, keyValuePair.Value, beginBoundary); byte[] parameterHeaderBytes = parameter.Encoding.GetBytes(parameterHeaderTemplate); memoryStream.Write(parameterHeaderBytes, 0, parameterHeaderBytes.Length); } } // 4.组装文件头数据体 到内存流中 string fileHeaderTemplate = string.Format("Content-Disposition: form-data; name="{0}"; filename="{1}"rnContent-Type: application/octet-streamrnrn", parameter.FileNameKey, parameter.FileNameValue); byte[] fileHeaderBytes = parameter.Encoding.GetBytes(fileHeaderTemplate); memoryStream.Write(fileHeaderBytes, 0, fileHeaderBytes.Length); // 5.组装结束分界线数据体 到内存流中 //memoryStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); // 6.获取二进制数据 postBytes = memoryStream.ToArray(); } // 7.HttpWebRequest 组装 HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(parameter.Url, UriKind.RelativeOrAbsolute)); //对发送的数据不使用缓存【重要、关键】 webRequest.AllowWriteStreamBuffering = false; webRequest.Method = "POST"; webRequest.Timeout = 1800000; webRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary); webRequest.ContentLength = postBytes.Length + parameter.UploadStream.Length + endBoundaryBytes.Length; webRequest.Headers.Add("X-Access-Token", "HSY715896176423170048"); if (Regex.IsMatch(parameter.Url, "^https://")) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult; } // 8.组装文件流 byte[] buffer = new byte[1024 * 1024 * 1]; int size = parameter.UploadStream.Read(buffer, 0, buffer.Length); Stream requestStream = webRequest.GetRequestStream(); requestStream.Write(postBytes, 0, postBytes.Length); while (size > 0) { requestStream.Write(buffer, 0, size); size = parameter.UploadStream.Read(buffer, 0, buffer.Length); } requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); requestStream.Close(); // 9.获取响应 using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()) { using (StreamReader reader = new StreamReader(webResponse.GetResponseStream(), parameter.Encoding)) { string body = reader.ReadToEnd(); reader.Close(); return body; } } }
上面的代码片段里面有针对请求https接口进行了证书处理顾增加一下代码:
static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return true; }
客户端调用上传:
public static void UploadFiles() { try { using (FileStream fs = new FileStream(@"C:UserswhDesktop各类型发票电子发票.jpg", FileMode.Open, FileAccess.Read)) { DictionarypostParameter = new Dictionary (); postParameter.Add("name", "heshang"); postParameter.Add("param", "1 2 3"); string result = Execute(new UploadParameterType { Url = "上传文件的服务端地址", UploadStream = fs, FileNameValue = "电子发票.jpg", PostParameters = postParameter }); } } catch (Exception) { throw; } }
最后上图postman:
最后还有个老哥的链接参考:
c#上传文件参考链接
最后加油!西红柿。