一、业务需求
在工作中遇到一个场景,软件bug或功能发布之后,会通知测试进行测试,要求写一个小工具能自动发送邮件,功能包含发送和抄送支持多个,因为只是通知没有写进附件功能,这个其他博客都有搜一下就可以了。
二、以下是实现代码
这里要注意如果接收者邮箱三种方式都没配置则需要手动输入,其他的没配置就是弹异常了。
这里使用的三种配置方其中的环境变量和命令行参数需要导入以下包,我用的是.net5.0所以版本都是选的5.0。使用其他版本不知道会产生什么问题,能一直就一致(前辈给的经验)

使用json方式有个坑就是要把json文件的属性里的复制到输出目录选成始终复制,Environment.CurrentDirectory才找得到它。

查看代码- using Microsoft.Extensions.Configuration;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- using System;
- using System.Net.Mail;
- using System.Text;
- namespace gct.sendmail
- {
- public class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine(WriteEmail(args).ToString());
- }
- public static string WriteEmail(string[] args)
- {
- IConfiguration configuration = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory)
- //json文件
- .AddJsonFile("appsettings.json")
- //系统参数
- .AddCommandLine(args)
- //环境变量
- .AddEnvironmentVariables()
- .Build();
- //发送者邮箱
- string strMailFrom = GetValue(configuration, "From:strMailFrom", "strMailFrom");
- //校验码
- string strCode = GetValue(configuration, "From:strCode", "strCode");
- //是否Html文件格式
- bool isHtml = !string.IsNullOrEmpty(configuration["From:isHtml"])?bool.Parse(configuration["From:isHtml"]) :
- configuration["isHtml"]!=null ? bool.Parse(configuration["isHtml"]) : false;
- //邮件服务器
- string strEmailServe = GetValue(configuration, "From:strEmailServe", "strEmailServe");
- //端口号
- int ePort = !string.IsNullOrEmpty(configuration["From:isHtml"])? int.Parse(configuration["From:ePort"]):
- !string.IsNullOrEmpty(configuration["ePort"]) ? int.Parse(configuration["ePort"]) : 25;
- //邮件发送名称
- string strMailFromName = GetValue(configuration, "From:strMailFromName", "strMailFromName");
- string strMailTo = GetValue(configuration, "To:strMailTo", "strMailTo");
- if (string.IsNullOrEmpty(strMailTo))
- {
- Console.WriteLine("请输入收件人邮箱,以" + ";" + "间隔!");
- strMailTo = Console.ReadLine().ToString();
- }
- //抄送
- string strMailCC = GetValue(configuration, "To:strMailCC", "strMailCC");
- //标题
- string strMailSubject = GetValue(configuration, "Content:strMailSubject", "strMailSubject");
- //正文
- string strMailBody = GetValue(configuration, "Content:strMailBody", "strMailBody");
- return SendEmail(strMailFrom, strMailTo, strMailCC, strMailSubject, strMailBody, isHtml, strCode, ePort, strEmailServe, strMailFromName);
- }
- /// <summary>
- /// 发送电子邮件
- /// </summary>
- /// <param name="mailFrom">邮件发送方</param>
- /// <param name="mailTo">邮件接收方</param>
- /// <param name="mailCC">抄送</param>
- /// <param name="mailHead">标题</param>
- /// <param name="mailBody">正文</param>
- /// <param name="isHtml">指示邮件正文是否为 HTML 格式。</param>
- /// <param name="code">校验码</param>
- /// <param name="ePort">端口号</param>
- /// <param name="emailServe">邮箱服务器</param>
- /// <param name="mailFromName">发件人名称</param>
- /// <returns></returns>
- public static string SendEmail(string mailFrom, string mailTo, string mailCC,
- string mailHead, string mailBody, bool isHtml,
- string code, int ePort,string emailServe,string mailFromName)
- {
- MailMessage eMail = new MailMessage();
- SmtpClient eClient = new SmtpClient(emailServe, ePort);
- eClient.Credentials = new System.Net.NetworkCredential(mailFrom, code);
- eClient.EnableSsl = true;
- eClient.UseDefaultCredentials = false;
- eMail.Subject = mailHead;
- eMail.SubjectEncoding = Encoding.UTF8;
- eMail.Body = mailBody;
- eMail.BodyEncoding = Encoding.UTF8;
- eMail.From = new MailAddress(mailFrom, mailFromName,Encoding.UTF8);
- string[] arrMailAddr;
- try
- {
- //用";"分割多个收件人.
- eMail.To.Clear();
- if (!string.IsNullOrEmpty(mailTo))
- {
- arrMailAddr = mailTo.Split(';');
- foreach (string strTo in arrMailAddr)
- {
- if (!string.IsNullOrEmpty(strTo))
- {
- eMail.To.Add(strTo);
- }
- }
- }
- //用";"分割多个抄送人.
- eMail.CC.Clear();
- if (!string.IsNullOrEmpty(mailCC))
- {
- arrMailAddr = mailCC.Split(';');
- foreach (string strCC in arrMailAddr)
- {
- if (!string.IsNullOrEmpty(strCC))
- {
- eMail.CC.Add(strCC);
- }
- }
- }
- if (isHtml)
- {
- eMail.IsBodyHtml = true;
- }
- else
- {
- eMail.IsBodyHtml = false;
- }
- eClient.Send(eMail);
- return "邮件已发送,请查收!";
- }
- catch (Exception ex)
- {
- return "邮件发送失败,原因:" + ex.Message.ToString();
- }
- }
- //获取配置值
- public static string GetValue(IConfiguration configuration,string value1,string value2)
- {
- if (!string.IsNullOrEmpty(configuration[value1]))
- {
- return configuration[value1];
- }
- return configuration[value2];
- }
- }
- }
复制代码 这里需要注意,邮箱发送需要校验码,我这里是用的qq邮箱,其他邮箱大概也要,我懒得截图了,以下为参考来源:.Net调用QQ邮箱发送邮件 - 樱满集 - 博客园 (cnblogs.com)
首先发送邮件要开启一个smtp的服务
第一步:打开qq邮箱点击设置:

第二步:点击账户

第三步:向下拉找到smtp字样的地方,然后全部开启

相信你能理解这句话,然后你开启的时候会自动弹出授权码,如果没有当时没有复制粘贴可以点击生成授权码 ,来重新生成:

第一种配置方式:json文件,以下是我的配置方式,取值格式是configuration["From:strCode"]
appsettings.json- {
- "From": {
- //发件人邮箱
- "strMailFrom": "",
- //邮箱服务器,以下是qq邮箱服务器
- "strEmailServe": "smtp.qq.com",
- //授权码(注意此处,是授权码你需要到qq邮箱里点设置开启Smtp服务,然后会提示你第三方登录时密码处填写授权码)
- "strCode": "",
- //是否为Html文件形式
- "isHtml": "false",
- //端口,默认25
- "ePort": "25",
- //发送者名称
- "strMailFromName": ""
- },
- "To": {
- //抄送,多个以英文符号;间隔
- "strMailCC": "",
- //收件人邮箱,多个以英文符号;间隔
- "strMailTo": ""
- },
- "Content": {
- //标题
- "strMailSubject": "邮件测试",
- //正文内容
- "strMailBody": "邮件测试,请勿回复"
- }
- }
复制代码 第二种配置方式,环境变量,除了在项目内能设置,系统的环境变量也能识别到,以下只距离项目内设置的,这里有个问题我还没弄清楚,弄到Linux环境里去之后项目里设置的好像没有生效,这里我验证之后再来更新,建议是使用json方式配置,优先级也是json优先其次环境变量再其次命令行参数。


第三种配置方式,命令行参数
这里很奇怪的是官方说明会用--开头,但取值的时候--是不生效的也就是说--str和str是一样的。具体的我也不知道,有兴趣的可以去官网了解。
以上分享就这些,写的不好或不对的地方欢迎指正。
转载请注明出处
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |