private static string DecodeField(string str) // 将字段值解码(含非ASCII码时) { string decodedField = ""; string[] fields = str.Split('?'); // 会分成5段,第2段为字符编码,第3段为字节编码,第4段为内容 if (fields.Length == 5) { string encodeType1 = fields[1]; // 字符编码 string encodeType2 = fields[2]; if (encodeType2 == "B") // 如果是Base64编码 { decodedField += MyEncoder.DecodeWithBase64(fields[3], Encoding.GetEncoding(encodeType1)); // 先转为字节数组,再以GBK解码 } else if (encodeType2 == "Q") // 如果是Quoted-printable编码 { decodedField += MyEncoder.DecodeWithQP(fields[3], Encoding.GetEncoding(encodeType1)); } else // 暂时不处理其他类型的编码 { decodedField += (fields[3] + " "); } } else // 不带编码,纯英文 { decodedField = str + " "; } return(decodedField); }
/* 将字符串转为信体结构 */ public static Body GetBody(string rawStr) { Body body = new Body(); string unfoledRawStr = rawStr.Replace("\r\n ", " ").Replace("\r\n\t", " "); // 展开字段 /* 处理Content-Type和Transfer-Encoding-Type */ string contentTypePattern = "(\r\n|\n)Content-Type:([^;]*);(.*)(\r\n|\n)"; // Content-Type匹配模式 string encodingTypePattern = "(\r\n|\n)Content-Transfer-Encoding:[ ]*(.*)[ ]*(\r\n|\n)"; // Transfer-Encoding-Type匹配模式 Match conmatch = Regex.Match(unfoledRawStr, contentTypePattern); Match enmatch = Regex.Match(unfoledRawStr, encodingTypePattern); if (!conmatch.Success || !enmatch.Success) // 两个必有属性必须匹配成功 { return(body); } string contentTypeStr = conmatch.Groups[2].Value.Trim().Trim('"').ToLower(); // 主属性 string otherAttributes = conmatch.Groups[3].Value; // 其他属性 body.ContentType = GetContentType(contentTypeStr); // 添加Content-Type body.EncodeType = GetEncodingType(enmatch.Groups[2].Value.Trim().Trim('"')); // 添加Transfer-Encoding-Type /* 依据不同的内容类型分别处理 */ if (contentTypeStr.Contains("multipart")) // 混合类型 { body.Boundary = GetBoundary(otherAttributes); body.Charset = GetCharset(otherAttributes); string boundary = "--" + body.Boundary; // 分割字符串 string endBoundary = "--" + body.Boundary + "--"; // 结尾字符串 string[] parts = Regex.Split(rawStr.Replace(endBoundary, boundary), boundary); // 按边界切割 /* 处理每个子部分 */ for (int i = 1; i < parts.Length; i++) // 忽略第一部分,因为是信头 { if (parts[i] == "\r\n" || parts[i] == "\r\n\r\n" || parts[i] == "") // 跳过无意义的部分 { continue; } body.SubBodies.Add(GetBody(parts[i])); // 递归处理子信体 } } else if (contentTypeStr.Contains("text")) // 文本类型 { body.Charset = GetCharset(otherAttributes); string[] strs = Regex.Split(rawStr, "\r\n\r\n"); string data = ""; for (int i = 1; i < strs.Length; i++) // 跳过信头 { if (strs[i] == "\r\n" || strs[i] == "\r\n\r\n" || strs[i] == "") // 跳过无意义的部分 { continue; } string contentStr; switch (body.EncodeType) // 依据不同编码进行解码 { case Transfer_Encoding.Base64: contentStr = strs[i].Replace("\r\n", ""); // 去除所有换行标记 data += (MyEncoder.DecodeWithBase64(contentStr, body.Charset) + "\n"); break; case Transfer_Encoding.Quoted_Printable: strs[i] += "\r\n"; // 每段结尾补一个\r\n,以避免QP编码换行标志被破坏 contentStr = strs[i].Replace("=\r\n", "").Replace("\r\n", ""); // 去除所有换行标记 data += (MyEncoder.DecodeWithQP(contentStr, body.Charset) + "\n"); break; case Transfer_Encoding.Bit8: contentStr = strs[i].Replace("\r\n", ""); // 去除所有换行标记 data += (MyEncoder.DecodeWithBit8(contentStr, body.Charset) + "\n"); break; case Transfer_Encoding.Bit7: contentStr = strs[i].Replace("\r\n", ""); // 去除所有换行标记 data += (contentStr + "\n"); break; default: contentStr = strs[i].Replace("\r\n", ""); // 去除所有换行标记 data += (contentStr + "\n"); break; } } body.Data = body.Charset.GetBytes(data); } else if (contentTypeStr.Contains("application")) // 应用类型 { body.Name = GetName(otherAttributes); body.Disposition = GetDisposition(rawStr); string[] paras = Regex.Split(rawStr, "\r\n\r\n"); byte[] data; switch (body.EncodeType) // 依据不同编码进行解码 { case Transfer_Encoding.Base64: data = MyEncoder.DecodeWithBase64(paras[1].Replace("\r\n", "")); break; case Transfer_Encoding.Quoted_Printable: data = MyEncoder.DecodeWithQP(paras[1].Replace("=\r\n", "").Replace("\r\n", "")); break; case Transfer_Encoding.Bit8: data = MyEncoder.DecodeWithBit8(paras[1].Replace("\r\n", "")); break; case Transfer_Encoding.Bit7: data = Encoding.Default.GetBytes(paras[1].Replace("\r\n", "")); break; default: data = Encoding.Default.GetBytes(paras[1].Replace("\r\n", "")); break; } body.Data = data; } else if (contentTypeStr.Contains("image")) // 图片类型 { body.Name = GetName(otherAttributes); string[] paras = Regex.Split(rawStr, "\r\n\r\n"); byte[] data; switch (body.EncodeType) // 依据不同编码进行解码 { case Transfer_Encoding.Base64: data = MyEncoder.DecodeWithBase64(paras[1].Replace("\r\n", "")); break; case Transfer_Encoding.Quoted_Printable: data = MyEncoder.DecodeWithQP(paras[1].Replace("=\r\n", "").Replace("\r\n", "")); break; case Transfer_Encoding.Bit8: data = MyEncoder.DecodeWithBit8(paras[1].Replace("\r\n", "")); break; case Transfer_Encoding.Bit7: data = Encoding.Default.GetBytes(paras[1].Replace("\r\n", "")); break; default: data = Encoding.Default.GetBytes(paras[1].Replace("\r\n", "")); break; } body.Data = data; } else { } return(body); }