一、业务需求

在工作中遇到一个场景,软件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是一样的。具体的我也不知道,有兴趣的可以去官网了解。

以上分享就这些,写的不好或不对的地方欢迎指正。

转载请注明出处

.net 发邮件的小工具,包含json,环境变量,命令行参数三种配置方式的更多相关文章

  1. iOS系统提供开发环境下命令行编译工具:xcodebuild

    iOS系统提供开发环境下命令行编译工具:xcodebuild[3] xcodebuild 在介绍xcodebuild之前,需要先弄清楚一些在XCode环境下的一些概念[4]: Workspace:简单 ...

  2. JSON的三种解析方式

    一.什么是JSON? JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度. JSON就是一串字符串 只不过元素会使用特定 ...

  3. Shell 参数(2) --解析命令行参数工具:getopts/getopt

    getopt 与 getopts 都是 Bash 中用来获取与分析命令行参数的工具,常用在 Shell 脚本中被用来分析脚本参数. 两者的比较 (1)getopts 是 Shell 内建命令,geto ...

  4. .NET 命令行参数包含应用程序路径吗?

    如果你关注过命令行参数,也许发现有时你会在命令行参数的第一个参数中中看到应用程序的路径,有时又不会.那么什么情况下有路径呢? 其实是否有路径只是取决于获取命令行参数的时候用的是什么方法.而这是 Win ...

  5. PHP 命令行参数解析工具类

    <?php/** * 命令行参数解析工具类 * @author guolinchao * @email luoyecb@163.com */class CommandLine{ // store ...

  6. 命令行参数 && json 协议 && 自定义 error 类型

    命令行参数 在写代码的时候,在运行程序做一些初始化操作的时候,往往会通过命令行传参数到程序中,那么就会用到命令行参数 例如,指定程序运行的模式和级别: go run HTTPServer.go --m ...

  7. Python 中命令行参数解析工具 docopt 安装和应用

    什么是 docopt? 1.docopt 是一种 Python 编写的命令行执行脚本的交互语言. 它是一种语言! 它是一种语言! 它是一种语言! 2.使用这种语言可以在自己的脚本中,添加一些规则限制. ...

  8. Go 命令行参数,JSON 序列化与反序列化

    #### Go 命令行参数,JSON 序列,反序列化这一节来学习一下Go 如果解析命令行参数,以及JSON 的序列化及反序列化; 命令行参数对于熟悉Linux 的同学来说比较清楚,如: ls -a , ...

  9. 小工具:天气查询 Vs自定义设置 DevGridControl中GridView排序问题 小工具:火车票查询 小工具:邮件发送 小工具:截图&简单图像处理

    小工具:天气查询   开发一个天气查询的工具主要由两步构成,一是数据的获取,二是数据的展示.  一.数据获取 数据获取又可以分为使用其它公司提供的API和手动抓取其它网站数据. 1. 某公司提供的AP ...

  10. iOS10打电话、发短信、发邮件等小功能

    注意:iOS10.0以后,使用openURL会有延迟,需要使用 openURL: options: completionHandler: 一.概要 本文中主要就是介绍在iOS中实现打电话.发短信.发邮 ...

随机推荐

  1. Detours 的使用

    Detours 是一个用于在 ARM, ARM64, X86, X64 和 IA64 机器上拦截二进制函数的库. Detours 最常用来拦截应用程序中的 win32 api 调用,比如添加调试工具. ...

  2. QT - Day 4

    1  界面布局 实现登录窗口 利用布局方式,给窗口类化 选取Widget进行布局,水平布局,垂直布局,栅格布局 给用户名.密码.登录.退出按钮进行布局 默认窗口和控件之间有9间隙,可以调整layout ...

  3. 【Azure 微服务】新创建的Service Fabric集群,如何从本地机器上连接到Service Fabric Explorer(Service Fabric状态/错误查看工具)呢?

    问题描述 当在Azure中成功创建一个Service Fabric Cluster 服务后,我们能够在它的Overview页面中发现 Service Fabric Explorer的终结点,但是打开后 ...

  4. 「实操」结合图数据库、图算法、机器学习、GNN 实现一个推荐系统

    本文是一个基于 NebulaGraph 上图算法.图数据库.机器学习.GNN 的推荐系统方法综述,大部分介绍的方法提供了 Playground 供大家学习. 基本概念 推荐系统诞生的初衷是解决互联网时 ...

  5. 淘宝电商api接口 获取商品详情 搜索商品

    iDataRiver平台 https://www.idatariver.com/zh-cn/ 提供开箱即用的taobao淘宝电商数据采集API,供用户按需调用. 接口使用详情请参考淘宝接口文档 接口列 ...

  6. 使用fastJson中的JSONObject对象简化POST请求传参-2022新项目

    一.业务场景 Java项目开发中,经常会用到远程调用,不管是POST请求,Feign远程调用,还是使用Resttemplate中的POST方法等等都需要传递参数. 可是如何更好的传递参数呢?之前自己开 ...

  7. MindSpore自定义算子中的张量维度问题

    技术背景 在前面的几篇博客中,我们介绍了MindSpore框架下使用CUDA来定义本地算子的基本方法,以及配合反向传播函数的使用,这里主要探讨一下MindSpore框架对于CUDA本地算子的输入输出的 ...

  8. CRC常用参数模型及C#代码实现

    目录 参数模型 算法实现 CRC-32 CRC-32/MPEG-2 表生成算法 参考资料 本文源码 参数模型 CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中 ...

  9. 微信自动信息发送助手WMR

    某信自动信息发送助手WMR 最近放假闲来无事,捣鼓了一下pyqt5,正好手上有每天定时大量群发消息的需求,正好就用pyqt5做个小应用练练手. 包含到的主要库:pyqt5.pyperclip.pyau ...

  10. float、double的精度、范围,在内存中的存储方式

    float.double的精度,在内存中的存储方式 一.浮点型变量在内存中的存储方式 Java的浮点数遵循IEEE 754标准,采用二进制数据的科学计数法来表示浮点数,float遵从的是IEEE R3 ...