예제 #1
0
        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);
        }
예제 #2
0
        private static string EncodeField(string str)                   // 将字段值编码(含非ASCII码时)
        {
            string utf8Str   = MyEncoder.EncodeWithUTF8(str);
            string base64Str = MyEncoder.EncodeWithBase64(utf8Str);

            string encodedFieldStr = String.Format("=?UTF-8?B?{0}?=", base64Str);

            return(encodedFieldStr);
        }
예제 #3
0
        /* 将字符串转为信体结构 */
        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);
        }
예제 #4
0
        private static string BodyToStr(Body body)                      // 将信体转为字符串
        {
            string bodyStr = "";

            // Content-Type
            if (body.IsMulti)
            {
                bodyStr += String.Format("Content-Type: {0};\r\n\tboundary=\"{1}\"\r\n", GetContentTypeStr(body.ContentType), body.Boundary);
            }
            else if (body.IsAttachment)
            {
                bodyStr += String.Format("Content-Type: {0};\r\n\tname=\"{1}\"\r\n", GetContentTypeStr(body.ContentType), body.Name);
            }
            else
            {
                bodyStr += String.Format("Content-Type: {0};\r\n\tcharset=\"{1}\"\r\n", GetContentTypeStr(body.ContentType), "UTF-8");
            }

            // Content-Transfer-Encoding
            if (!body.IsMulti)
            {
                bodyStr += String.Format("Content-Transfer-Encoding: base64\r\n");
            }

            // Other Attributes
            if (body.IsAttachment)
            {
                bodyStr += String.Format("Content-Disposition: attachment; filename=\"{0}\"\r\n", body.Name);
            }

            /* 构建邮件体 */
            if (body.IsMulti)
            {
                foreach (Body subBody in body.SubBodies)
                {
                    bodyStr += String.Format("\r\n--{0}\r\n", body.Boundary);       // 添加起头
                    bodyStr += BodyToStr(subBody);
                }
                bodyStr += String.Format("\r\n--{0}--\r\n", body.Boundary);         // 添加结尾
            }
            else
            {
                string base64Data = MyEncoder.EncodeWithBase64(body.Data);          // 编码为base64
                string dstStr     = "";
                dstStr += "\r\n";
                for (int i = 0; i < base64Data.Length; i += 75)                     // 保证每行不超过80字符
                {
                    if (i + 75 < base64Data.Length)
                    {
                        dstStr += base64Data.Substring(i, 75) + "\r\n";
                    }
                    else
                    {
                        dstStr += base64Data.Substring(i, base64Data.Length - i) + "\r\n";
                    }
                }
                dstStr  += "\r\n";
                bodyStr += dstStr;
            }

            return(bodyStr);
        }
예제 #5
0
        /* 发送邮件 */
        private void SendBtnClick(object sender, RoutedEventArgs e)
        {
            if (ToTextBox.Text != null & DataTextBox.Text != null)
            {
                smtp.Init(smtpServerAddr, 25);                       // 初始化并登录邮箱
                smtp.Login(user, pwd);

                Email email = new Email();          // 创建一封邮件

                /* 信头 */
                Heading head = new Heading()
                {
                    From    = user,
                    To      = ToTextBox.Text,
                    Subject = SubjectTextBox.Text == null ? "Unknown" : SubjectTextBox.Text,     // TODO: 提取部分Data作为subject
                };

                /* 信体 */
                Body body = new Body();

                UTF8Encoding utf8     = new UTF8Encoding();
                byte[]       b        = utf8.GetBytes(MyEncoder.EncodeWithUTF8(DataTextBox.Text));
                Body         textBody = new Body()
                {
                    ContentType = Content_Type.Text_Plain,
                    Data        = b
                };

                if (attachments.Count != 0)
                {
                    body.ContentType = Content_Type.Multi_Mixed;
                    body.SubBodies.Add(textBody);
                    foreach (Attachment attachment in attachments)
                    {
                        Body attachBody = new Body()
                        {
                            ContentType = attachment.ContentType,
                            Name        = attachment.Name,
                            Data        = attachment.Data,
                        };
                        body.SubBodies.Add(attachBody);
                    }
                    attachments.Clear();
                    SendAttachmentListBox.ItemsSource = null;
                    SendAttachmentListBox.ItemsSource = attachments;
                }
                else
                {
                    body = textBody;
                }

                email.Head    = head;
                email.Content = body;

                smtp.SendEmail(email);          // 发送邮件
                smtp.Close();
            }
            else
            {
                // 显示错误
            }
        }