/// <summary> /// 对multipart/form-data数据流进行解析 /// </summary> /// <param name="stream"></param> /// <param name="encoding"></param> /// <returns></returns> public static FrameDLRObject ParseMultipartFormData(Stream stream, Encoding encoding) { FrameDLRObject rtn = FrameDLRObject.CreateInstance(FrameDLRFlags.SensitiveCase); stream.Seek(0, SeekOrigin.Begin); // Read the stream into a byte array byte[] data = new byte[stream.Length]; stream.Read(data, 0, data.Length); string str = encoding.GetString(data); // Copy to a string for header parsing string content = encoding.GetString(data); // The first line should contain the delimiter int delimiterEndIndex = content.IndexOf("\r\n"); if (delimiterEndIndex > -1) { string delimiter = content.Substring(0, content.IndexOf("\r\n")); int delimiterByteLength = encoding.GetByteCount(delimiter); string[] sections = content.Split(new string[] { delimiter }, StringSplitOptions.RemoveEmptyEntries); var splitindexs = ComFunc.BytesSplit(data, delimiter, Encoding.UTF8); var i = 0; foreach (string s in sections) { //搜索分隔喘在byte[]中所在的位置 if (s.Contains("Content-Disposition")) { // If we find "Content-Disposition", this is a valid multi-part section // Now, look for the "name" parameter Match nameMatch = new Regex(@"(?<=name\=\"")(.*?)(?=\"")").Match(s); string name = nameMatch.Value.Trim().ToLower(); // Look for Content-Type Regex re = new Regex(@"(?<=Content\-Type:)(.*?)(?=\r\n\r\n)"); Match contentTypeMatch = re.Match(s); // Look for filename re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")"); Match filenameMatch = re.Match(s); if (contentTypeMatch.Success || filenameMatch.Success) { // Set properties var contentype = contentTypeMatch.Value.Trim(); var filename = filenameMatch.Value.Trim(); // Get the start & end indexes of the file contents int startIndex = contentTypeMatch.Index + contentTypeMatch.Length + "\r\n\r\n".Length; var prestr = s.Substring(0, startIndex); startIndex = encoding.GetByteCount(prestr) + splitindexs[i] + delimiterByteLength; var endIndex = (i + 1) < splitindexs.Length ? splitindexs[i + 1] : data.Length - 1; //清除首位的换行符 for (int j = 0; j < 2; j++) { if (data[startIndex] == 10 || data[startIndex] == 13) { startIndex += 1; } if (data[endIndex - 1] == 10 || data[endIndex - 1] == 13) { endIndex -= 1; } } var contentLength = endIndex - startIndex; var fileData = new byte[contentLength]; Array.Copy(data, startIndex, fileData, 0, fileData.Length); var ms = new MemoryStream(); ms.Write(fileData, 0, fileData.Length); var fuf = new FrameUploadFile(filename, contentype, ms, encoding); rtn.SetValue(name, fuf); } else if (!string.IsNullOrWhiteSpace(name)) { // Get the start & end indexes of the file contents int startIndex = nameMatch.Index + nameMatch.Length + "\r\n\r\n".Length; rtn.SetValue(name, s.Substring(startIndex).TrimEnd(new char[] { '\r', '\n' }).Trim()); } } i++; } } return(rtn); }