如何通过WCF实现高效图片上传功能?

2026-03-30 14:571阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1567个文字,预计阅读时间需要7分钟。

如何通过WCF实现高效图片上传功能?

0、背景+老项目使用WCF提供web服务,现在开发安卓原生应用需要上传图片,网上找到了一些资料和代码,发现文件中文名处理有点异常,修改后输出。

1、代码

1.1、C

如何通过WCF实现高效图片上传功能?

0、背景

老项目使用WCF 提供web服务,现在开发安卓原生应用需要上传图片,网上找了些资料和代码发现文件中文名称处理有点异常,修改后贴出来。

1、代码

1.1 C#后端代码

服务接口 [OperationContract] [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)] Dictionary<string, string> ModifyImg(Stream image); 服务实现类 public Dictionary<string, string> ModifyImg(Stream image) { BOUploadImg bOUploadImg = new BOUploadImg(); var dic = bOUploadImg.UploadWithFormData(image); BOFactory.boQmsBarcodeImage.Save(dic); return dic; }

public class BOUploadImg { public Dictionary<string, string> Upload(Stream file) { Dictionary<string, string> dic = new Dictionary<string, string>(); try { string rootPath = "~/upload/"; string realRoot = System.Configuration.ConfigurationManager.AppSettings["RemoteUploadFileDir"]; using (MemoryStream ms = new MemoryStream()) { file.CopyTo(ms); ms.Position = 0; using (StreamReader sr = new StreamReader(ms)) { int firstLineLen = Encoding.UTF8.GetBytes(sr.ReadLine() ?? "").Length; var position = firstLineLen + 2; var line = sr.ReadLine(); var filename = ""; var ID = DateTime.Now.ToString("yyyyMMddHHmmssffff", DateTimeFormatInfo.InvariantInfo); if (!string.IsNullOrEmpty(line)) { int idx = line.IndexOf("filename", StringComparison.CurrentCultureIgnoreCase); filename += line.Substring(idx + 9).Replace("\"", ""); } string Extension = ""; int index = filename.LastIndexOf('.'); if (index > 0) { Extension = filename.Substring(filename.LastIndexOf('.') + 1); } while (line != null) { // 特别是第二行含文件名称,可能含中文,所以不能直接用line.Length // 因为line.Length是字符个数,不是字节个数 position += Encoding.UTF8.GetBytes(line).Length + 2; if (line == "") break; line = sr.ReadLine(); } ms.Position = position; ms.SetLength(ms.Length - (firstLineLen + 6)); var uploadStream = new MemoryStream(); ms.CopyTo(uploadStream); uploadStream.Position = 0; try { //文件存储地址 string folder = ""; string dirPath = CheckTodayDir(realRoot, out folder); string realPath = Path.Combine(dirPath, string.Format("{0}.{1}", ID, Extension)); string IMAGE_REAL_NAME = string.Format("{0}.{1}", ID, Extension); string IMAGE_PATH = rootPath + folder + "/" + IMAGE_REAL_NAME; dic.Add("FILE_REAL_NAME", IMAGE_REAL_NAME); dic.Add("FILE_PATH", IMAGE_PATH);//URL PATH dic.Add("FILE_OLD_NAME", filename); dic.Add("FILE_EXTENSION", Extension); File.WriteAllBytes(realPath, uploadStream.ToArray()); } catch { } } } return dic; } catch (Exception) { return dic; } } public Dictionary<string, string> UploadWithFormData(Stream stream) { Dictionary<string, string> dic = new Dictionary<string, string>(); try { string rootPath = "~/upload/"; string realRoot = System.Configuration.ConfigurationManager.AppSettings["RemoteUploadFileDir"]; FormdataCase formdataCase = new FormdataCase(stream); var ID = DateTime.Now.ToString("yyyyMMddHHmmssffff", DateTimeFormatInfo.InvariantInfo); string Extension = ""; int index = formdataCase.Filename.LastIndexOf('.'); if (index > 0) { Extension = formdataCase.Filename.Substring(formdataCase.Filename.LastIndexOf('.') + 1); } //文件存储地址 string folder = ""; string dirPath = CheckTodayDir(realRoot, out folder); string realPath = Path.Combine(dirPath, string.Format("{0}.{1}", ID, Extension)); string IMAGE_REAL_NAME = string.Format("{0}.{1}", ID, Extension); string IMAGE_PATH = rootPath + folder + "/" + IMAGE_REAL_NAME; dic.Add("FILE_REAL_NAME", IMAGE_REAL_NAME); dic.Add("FILE_PATH", IMAGE_PATH);//URL PATH dic.Add("FILE_OLD_NAME", formdataCase.Filename); dic.Add("FILE_EXTENSION", Extension); if(formdataCase.Parameters != null && formdataCase.Parameters.Count > 0) { foreach(var keyValue in formdataCase.Parameters) { dic.Add(keyValue.Key, keyValue.Value); } } File.WriteAllBytes(realPath, formdataCase.FileContents.ToArray()); return dic; } catch(Exception ex) { dic.Add("ERROR", ex.Message); return dic; } } private static string CheckTodayDir(string root, out string folder) { folder = DateTime.Now.ToString("yyyyMMdd"); string path = Path.Combine(root, folder); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } return path; } } public class FormdataCase { /// <summary> /// 参数集合 /// </summary> public IDictionary<string, string> Parameters = new Dictionary<string, string>(); /// <summary> /// 是否解析成功 /// </summary> public bool Success { get; private set; } /// <summary> /// 请求类型 /// </summary> public string ContentType { get; private set; } /// <summary> /// 上传的文件名 /// </summary> public string Filename { get; private set; } /// <summary> /// 上传的文件内容 /// </summary> public byte[] FileContents { get; private set; } /// <summary> /// 解析multipart/form-data格式的文件请求,默认编码为utf8 /// </summary> /// <param name="stream"></param> public FormdataCase(Stream stream) { Parse(stream, Encoding.UTF8); } /// <summary> /// 解析form-data /// </summary> /// <param name="stream">可带参数,并不是只可以放一个文件</param> /// <param name="encoding">utf8</param> private void Parse(Stream stream, Encoding encoding) { Success = false; var data = ToByteArray(stream);//将文件流转为byte[] var content = encoding.GetString(data);//将byte[]转为string字符串 var delimiterEndIndex = content.IndexOf("\r\n", StringComparison.Ordinal); if (delimiterEndIndex > -1) { var delimiter = content.Substring(0, content.IndexOf("\r\n", StringComparison.Ordinal)).Trim(); var sections = content.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries); foreach (var s in sections) { if (s.Contains("Content-Disposition")) { //获取form-data中的参数名称 var nameMatch = new Regex(@"(?<=name\=\"")(.*?)(?=\"")").Match(s); var name = nameMatch.Value.Trim().ToLower(); //这里由于文件的参数名称为file,当获取到参数名称等于 file时,可以将文件内容截取出来,参数不是文件时将该参数存入泛型集合Parameters中。 if (name == "file") { var re = new Regex(@"(?<=Content\-Type:)(.*?)(?=\r\n\r\n)"); var contentTypeMatch = re.Match(content); //获取文件名 re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")"); var filenameMatch = re.Match(content); //截取文件 if (contentTypeMatch.Success && filenameMatch.Success) { ContentType = contentTypeMatch.Value.Trim(); Filename = filenameMatch.Value.Trim(); var startIndex = contentTypeMatch.Index + contentTypeMatch.Length + "\r\n\r\n".Length; //这里取到的是字符数有中文需要取字节数 startIndex = Encoding.UTF8.GetBytes(content.Substring(0, startIndex)).Length; var delimiterBytes = encoding.GetBytes("\r\n" + delimiter); var endIndex = IndexOf(data, delimiterBytes, startIndex); var contentLength = endIndex - startIndex;//计算文件流长度 var fileData = new byte[contentLength]; Buffer.BlockCopy(data, startIndex, fileData, 0, contentLength); FileContents = fileData; } } else if (!string.IsNullOrWhiteSpace(name)) { //截取非文件参数,并将参数名称与参数值保存在泛型集合Parameters中。 var startIndex = nameMatch.Index + nameMatch.Length + "\r\n\r\n".Length; Parameters.Add(name, s.Substring(startIndex).TrimEnd('\r', '\n').Trim()); } } } if (FileContents != null || Parameters.Count != 0) { Success = true; } } } /// <summary> /// 获取文件流末尾 /// </summary> /// <param name="searchWithin"></param> /// <param name="serachFor"></param> /// <param name="startIndex"></param> /// <returns></returns> public static int IndexOf(byte[] searchWithin, byte[] serachFor, int startIndex) { var index = 0; var startPos = Array.IndexOf(searchWithin, serachFor[0], startIndex); if (startPos != -1) { while (startPos + index < searchWithin.Length) { if (searchWithin[startPos + index] == serachFor[index]) { index++; if (index == serachFor.Length) { return startPos; } } else { startPos = Array.IndexOf(searchWithin, serachFor[0], startPos + index); if (startPos == -1) { return -1; } index = 0; } } } return -1; } /// <summary> /// 将stream转为byte[] /// </summary> /// <param name="stream"></param> /// <returns></returns> public static byte[] ToByteArray(Stream stream) { var buffer = new byte[32768]; using (var ms = new MemoryStream()) { while (true) { var read = stream.Read(buffer, 0, buffer.Length); if (read <= 0) { return ms.ToArray(); } ms.Write(buffer, 0, read); } } } }

1.2 HTML 上传测试

<html> <head>upload file to wcf iis</head> <script src="ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.4.min.js"></script> <body> <input id="imgput" type="file" accept="image/*" onchange="selectimg(this);" /> <img id='imgtest' src="#" alt="Alternate Text" width="25px" /> <script type="text/javascript"> function selectimg(file) { var url = null; if (window.createobjectURL) { url = window.createObjectURL(file.files[0]);//预览图片,浏览器支持不同 } else if (window.URL) { url = window.URL.createObjectURL(file.files[0]); } else if (window.webkitURL) { url = window.webkitURL.createObjectURL(file.files[0]); } var pimg = file.files[0];//获取图片文件 if (pimg.size > 1024 * 500) { alert("文件不能超过500KB"); } else { var format = new FormData();//构建表单信息 var name = "file"; format.append(name, pimg); format.append("age", 39); format.append("address", "nanjing"); $("#imgtest").attr("src", url); $.ajax({ url: "localhost:17880/MESOperationService.svc/ModifyImg", type: "post", data: format, processData: false,//这里设置为false,回传流文件 dataType: 'json', contentType: 'application/x-www-form-urlencoded', async: false, success: function (result) { alert(JSON.stringify(result)); } }); } } </script> </body> </html>

本文共计1567个文字,预计阅读时间需要7分钟。

如何通过WCF实现高效图片上传功能?

0、背景+老项目使用WCF提供web服务,现在开发安卓原生应用需要上传图片,网上找到了一些资料和代码,发现文件中文名处理有点异常,修改后输出。

1、代码

1.1、C

如何通过WCF实现高效图片上传功能?

0、背景

老项目使用WCF 提供web服务,现在开发安卓原生应用需要上传图片,网上找了些资料和代码发现文件中文名称处理有点异常,修改后贴出来。

1、代码

1.1 C#后端代码

服务接口 [OperationContract] [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)] Dictionary<string, string> ModifyImg(Stream image); 服务实现类 public Dictionary<string, string> ModifyImg(Stream image) { BOUploadImg bOUploadImg = new BOUploadImg(); var dic = bOUploadImg.UploadWithFormData(image); BOFactory.boQmsBarcodeImage.Save(dic); return dic; }

public class BOUploadImg { public Dictionary<string, string> Upload(Stream file) { Dictionary<string, string> dic = new Dictionary<string, string>(); try { string rootPath = "~/upload/"; string realRoot = System.Configuration.ConfigurationManager.AppSettings["RemoteUploadFileDir"]; using (MemoryStream ms = new MemoryStream()) { file.CopyTo(ms); ms.Position = 0; using (StreamReader sr = new StreamReader(ms)) { int firstLineLen = Encoding.UTF8.GetBytes(sr.ReadLine() ?? "").Length; var position = firstLineLen + 2; var line = sr.ReadLine(); var filename = ""; var ID = DateTime.Now.ToString("yyyyMMddHHmmssffff", DateTimeFormatInfo.InvariantInfo); if (!string.IsNullOrEmpty(line)) { int idx = line.IndexOf("filename", StringComparison.CurrentCultureIgnoreCase); filename += line.Substring(idx + 9).Replace("\"", ""); } string Extension = ""; int index = filename.LastIndexOf('.'); if (index > 0) { Extension = filename.Substring(filename.LastIndexOf('.') + 1); } while (line != null) { // 特别是第二行含文件名称,可能含中文,所以不能直接用line.Length // 因为line.Length是字符个数,不是字节个数 position += Encoding.UTF8.GetBytes(line).Length + 2; if (line == "") break; line = sr.ReadLine(); } ms.Position = position; ms.SetLength(ms.Length - (firstLineLen + 6)); var uploadStream = new MemoryStream(); ms.CopyTo(uploadStream); uploadStream.Position = 0; try { //文件存储地址 string folder = ""; string dirPath = CheckTodayDir(realRoot, out folder); string realPath = Path.Combine(dirPath, string.Format("{0}.{1}", ID, Extension)); string IMAGE_REAL_NAME = string.Format("{0}.{1}", ID, Extension); string IMAGE_PATH = rootPath + folder + "/" + IMAGE_REAL_NAME; dic.Add("FILE_REAL_NAME", IMAGE_REAL_NAME); dic.Add("FILE_PATH", IMAGE_PATH);//URL PATH dic.Add("FILE_OLD_NAME", filename); dic.Add("FILE_EXTENSION", Extension); File.WriteAllBytes(realPath, uploadStream.ToArray()); } catch { } } } return dic; } catch (Exception) { return dic; } } public Dictionary<string, string> UploadWithFormData(Stream stream) { Dictionary<string, string> dic = new Dictionary<string, string>(); try { string rootPath = "~/upload/"; string realRoot = System.Configuration.ConfigurationManager.AppSettings["RemoteUploadFileDir"]; FormdataCase formdataCase = new FormdataCase(stream); var ID = DateTime.Now.ToString("yyyyMMddHHmmssffff", DateTimeFormatInfo.InvariantInfo); string Extension = ""; int index = formdataCase.Filename.LastIndexOf('.'); if (index > 0) { Extension = formdataCase.Filename.Substring(formdataCase.Filename.LastIndexOf('.') + 1); } //文件存储地址 string folder = ""; string dirPath = CheckTodayDir(realRoot, out folder); string realPath = Path.Combine(dirPath, string.Format("{0}.{1}", ID, Extension)); string IMAGE_REAL_NAME = string.Format("{0}.{1}", ID, Extension); string IMAGE_PATH = rootPath + folder + "/" + IMAGE_REAL_NAME; dic.Add("FILE_REAL_NAME", IMAGE_REAL_NAME); dic.Add("FILE_PATH", IMAGE_PATH);//URL PATH dic.Add("FILE_OLD_NAME", formdataCase.Filename); dic.Add("FILE_EXTENSION", Extension); if(formdataCase.Parameters != null && formdataCase.Parameters.Count > 0) { foreach(var keyValue in formdataCase.Parameters) { dic.Add(keyValue.Key, keyValue.Value); } } File.WriteAllBytes(realPath, formdataCase.FileContents.ToArray()); return dic; } catch(Exception ex) { dic.Add("ERROR", ex.Message); return dic; } } private static string CheckTodayDir(string root, out string folder) { folder = DateTime.Now.ToString("yyyyMMdd"); string path = Path.Combine(root, folder); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } return path; } } public class FormdataCase { /// <summary> /// 参数集合 /// </summary> public IDictionary<string, string> Parameters = new Dictionary<string, string>(); /// <summary> /// 是否解析成功 /// </summary> public bool Success { get; private set; } /// <summary> /// 请求类型 /// </summary> public string ContentType { get; private set; } /// <summary> /// 上传的文件名 /// </summary> public string Filename { get; private set; } /// <summary> /// 上传的文件内容 /// </summary> public byte[] FileContents { get; private set; } /// <summary> /// 解析multipart/form-data格式的文件请求,默认编码为utf8 /// </summary> /// <param name="stream"></param> public FormdataCase(Stream stream) { Parse(stream, Encoding.UTF8); } /// <summary> /// 解析form-data /// </summary> /// <param name="stream">可带参数,并不是只可以放一个文件</param> /// <param name="encoding">utf8</param> private void Parse(Stream stream, Encoding encoding) { Success = false; var data = ToByteArray(stream);//将文件流转为byte[] var content = encoding.GetString(data);//将byte[]转为string字符串 var delimiterEndIndex = content.IndexOf("\r\n", StringComparison.Ordinal); if (delimiterEndIndex > -1) { var delimiter = content.Substring(0, content.IndexOf("\r\n", StringComparison.Ordinal)).Trim(); var sections = content.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries); foreach (var s in sections) { if (s.Contains("Content-Disposition")) { //获取form-data中的参数名称 var nameMatch = new Regex(@"(?<=name\=\"")(.*?)(?=\"")").Match(s); var name = nameMatch.Value.Trim().ToLower(); //这里由于文件的参数名称为file,当获取到参数名称等于 file时,可以将文件内容截取出来,参数不是文件时将该参数存入泛型集合Parameters中。 if (name == "file") { var re = new Regex(@"(?<=Content\-Type:)(.*?)(?=\r\n\r\n)"); var contentTypeMatch = re.Match(content); //获取文件名 re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")"); var filenameMatch = re.Match(content); //截取文件 if (contentTypeMatch.Success && filenameMatch.Success) { ContentType = contentTypeMatch.Value.Trim(); Filename = filenameMatch.Value.Trim(); var startIndex = contentTypeMatch.Index + contentTypeMatch.Length + "\r\n\r\n".Length; //这里取到的是字符数有中文需要取字节数 startIndex = Encoding.UTF8.GetBytes(content.Substring(0, startIndex)).Length; var delimiterBytes = encoding.GetBytes("\r\n" + delimiter); var endIndex = IndexOf(data, delimiterBytes, startIndex); var contentLength = endIndex - startIndex;//计算文件流长度 var fileData = new byte[contentLength]; Buffer.BlockCopy(data, startIndex, fileData, 0, contentLength); FileContents = fileData; } } else if (!string.IsNullOrWhiteSpace(name)) { //截取非文件参数,并将参数名称与参数值保存在泛型集合Parameters中。 var startIndex = nameMatch.Index + nameMatch.Length + "\r\n\r\n".Length; Parameters.Add(name, s.Substring(startIndex).TrimEnd('\r', '\n').Trim()); } } } if (FileContents != null || Parameters.Count != 0) { Success = true; } } } /// <summary> /// 获取文件流末尾 /// </summary> /// <param name="searchWithin"></param> /// <param name="serachFor"></param> /// <param name="startIndex"></param> /// <returns></returns> public static int IndexOf(byte[] searchWithin, byte[] serachFor, int startIndex) { var index = 0; var startPos = Array.IndexOf(searchWithin, serachFor[0], startIndex); if (startPos != -1) { while (startPos + index < searchWithin.Length) { if (searchWithin[startPos + index] == serachFor[index]) { index++; if (index == serachFor.Length) { return startPos; } } else { startPos = Array.IndexOf(searchWithin, serachFor[0], startPos + index); if (startPos == -1) { return -1; } index = 0; } } } return -1; } /// <summary> /// 将stream转为byte[] /// </summary> /// <param name="stream"></param> /// <returns></returns> public static byte[] ToByteArray(Stream stream) { var buffer = new byte[32768]; using (var ms = new MemoryStream()) { while (true) { var read = stream.Read(buffer, 0, buffer.Length); if (read <= 0) { return ms.ToArray(); } ms.Write(buffer, 0, read); } } } }

1.2 HTML 上传测试

<html> <head>upload file to wcf iis</head> <script src="ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.4.min.js"></script> <body> <input id="imgput" type="file" accept="image/*" onchange="selectimg(this);" /> <img id='imgtest' src="#" alt="Alternate Text" width="25px" /> <script type="text/javascript"> function selectimg(file) { var url = null; if (window.createobjectURL) { url = window.createObjectURL(file.files[0]);//预览图片,浏览器支持不同 } else if (window.URL) { url = window.URL.createObjectURL(file.files[0]); } else if (window.webkitURL) { url = window.webkitURL.createObjectURL(file.files[0]); } var pimg = file.files[0];//获取图片文件 if (pimg.size > 1024 * 500) { alert("文件不能超过500KB"); } else { var format = new FormData();//构建表单信息 var name = "file"; format.append(name, pimg); format.append("age", 39); format.append("address", "nanjing"); $("#imgtest").attr("src", url); $.ajax({ url: "localhost:17880/MESOperationService.svc/ModifyImg", type: "post", data: format, processData: false,//这里设置为false,回传流文件 dataType: 'json', contentType: 'application/x-www-form-urlencoded', async: false, success: function (result) { alert(JSON.stringify(result)); } }); } } </script> </body> </html>