当前位置 : 主页 > 网络编程 > net编程 >

通过WCF 上传图片

来源:互联网 收集:自由互联 发布时间:2023-09-06
0、背景 老项目使用WCF 提供web服务,现在开发安卓原生应用需要上传图片,网上找了些资料和代码发现文件中文名称处理有点异常,修改后贴出来。 1、代码 1.1 C#后端代码 服务接口[O

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="https://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: "http://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>
【感谢龙石为本站提供数据api平台http://www.longshidata.com/pages/exchange.html】
网友评论