.net 发邮件的小工具,包含json,环境变量,命令行参数三种配置方式
一、业务需求
在工作中遇到一个场景,软件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,环境变量,命令行参数三种配置方式的更多相关文章
- iOS系统提供开发环境下命令行编译工具:xcodebuild
iOS系统提供开发环境下命令行编译工具:xcodebuild[3] xcodebuild 在介绍xcodebuild之前,需要先弄清楚一些在XCode环境下的一些概念[4]: Workspace:简单 ...
- JSON的三种解析方式
一.什么是JSON? JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度. JSON就是一串字符串 只不过元素会使用特定 ...
- Shell 参数(2) --解析命令行参数工具:getopts/getopt
getopt 与 getopts 都是 Bash 中用来获取与分析命令行参数的工具,常用在 Shell 脚本中被用来分析脚本参数. 两者的比较 (1)getopts 是 Shell 内建命令,geto ...
- .NET 命令行参数包含应用程序路径吗?
如果你关注过命令行参数,也许发现有时你会在命令行参数的第一个参数中中看到应用程序的路径,有时又不会.那么什么情况下有路径呢? 其实是否有路径只是取决于获取命令行参数的时候用的是什么方法.而这是 Win ...
- PHP 命令行参数解析工具类
<?php/** * 命令行参数解析工具类 * @author guolinchao * @email luoyecb@163.com */class CommandLine{ // store ...
- 命令行参数 && json 协议 && 自定义 error 类型
命令行参数 在写代码的时候,在运行程序做一些初始化操作的时候,往往会通过命令行传参数到程序中,那么就会用到命令行参数 例如,指定程序运行的模式和级别: go run HTTPServer.go --m ...
- Python 中命令行参数解析工具 docopt 安装和应用
什么是 docopt? 1.docopt 是一种 Python 编写的命令行执行脚本的交互语言. 它是一种语言! 它是一种语言! 它是一种语言! 2.使用这种语言可以在自己的脚本中,添加一些规则限制. ...
- Go 命令行参数,JSON 序列化与反序列化
#### Go 命令行参数,JSON 序列,反序列化这一节来学习一下Go 如果解析命令行参数,以及JSON 的序列化及反序列化; 命令行参数对于熟悉Linux 的同学来说比较清楚,如: ls -a , ...
- 小工具:天气查询 Vs自定义设置 DevGridControl中GridView排序问题 小工具:火车票查询 小工具:邮件发送 小工具:截图&简单图像处理
小工具:天气查询 开发一个天气查询的工具主要由两步构成,一是数据的获取,二是数据的展示. 一.数据获取 数据获取又可以分为使用其它公司提供的API和手动抓取其它网站数据. 1. 某公司提供的AP ...
- iOS10打电话、发短信、发邮件等小功能
注意:iOS10.0以后,使用openURL会有延迟,需要使用 openURL: options: completionHandler: 一.概要 本文中主要就是介绍在iOS中实现打电话.发短信.发邮 ...
随机推荐
- 《系列一》-- 5、xml配置文件解析之[自定义]命名空间[标签]的解析
阅读之前要注意的东西:本文就是主打流水账式的源码阅读,主导的是一个参考,主要内容需要看官自己去源码中验证.全系列文章基于 spring 源码 5.x 版本. Spring源码阅读系列--全局目录.md ...
- 【Android 逆向】apk反编译后重打包
1. 执行 apktool b smali_dir smali_dir 为反编译出来的数据目录 执行后可能会报错 I: Building resources... W: /root/Desktop/t ...
- [BUUCTF][WEB][极客大挑战 2019]PHP 1
打开靶机URL 看到字面提示 因为每次猫猫都在我键盘上乱跳,所以我有一个良好的备份网站的习惯不愧是我!!! 说明该网站有备份,说不定放在了Http服务器的某个目录下 那么这里我们可以用dirsearc ...
- 进度条模块之tqdm
导入模块 from tqdm import tqdm import time ''' desc 描述 ncols 进度条总长度 可修改 range(1000) 封装迭代器 ''' for i in t ...
- Navicat 12连接mysql8.x报错2059 - authentication plugin 'caching_sha2_password' 解决办法
// %表示远程连接允许所有ip,如果只是连接本地,将%改为localhost即可 ALTER USER 'root'@'%' IDENTIFIED BY '你自己的mysql的密码' PASSWOR ...
- CXP2.0的相机是否可以使用CXP1.1的Grabber
可以 答案是肯定的. 目前CXP共有2个发布版本: 2011年发布CXP1.1 2021年发布CXP2.1,向后兼容,新标准增加了同步功能.数据率放大了一倍. 只要是符合CXP标准.接插件匹配,那么C ...
- oracle不等于1怎么查?
空值null比较特殊,它不能通过=或者<>进行查询,只能用is null或者is not null进行查询,例如你的数据中有null值,那么用 字段名=1,字段名<>1,字段名 ...
- VIM初使化
vim ~/.vimrc #设置编码 set encoding=utf-8 fileencodings=ucs-bom,utf-8,cp936 #显示行号 set number #一个tab为4个空格 ...
- 【Azure 存储服务】ADLS Gen 2 Backup/软删除/Version管理/快照等功能参考资料
问题描述 ADLS Gen 2 存储的备份,软删除和version管理, 快照等功能应该怎么启用? 问题回答 存储的备份 测试显示 Premium 定价层 的 ADLS Gen 2 在中国区Azure ...
- MySQL之过滤条件
[一]筛选过滤条件 [1]查询语句 -- 查询当前表中的指定字段的数据 select id,name from emp where id > 3; [2]创建数据表 create databas ...