Asp.Net Core MailKit 完美附件(中文名、长文件名)
最近在使用MailKit组件发送邮件,看了一些博客其实还是蛮简单的,但是发送附件的时候却产生了不小的问题,附件的中文名字是乱码的,或者附件的名字过长就会无效,附件的名字在QQ邮箱中会变成类似
tcmime.1046.1479.1696.bin这样问文件名而在163邮箱中则可能变成类似
ATT00002.docx的名称。如果你也遇到了这样的问题,那么我想你一定很期待接下来的解决办法。
解决文件名不能使用中文
原因是字符编码的问题
MimePart attachment = null;
var fs = new FileStream(path, FileMode.Open);
list.Add(fs);
attachment = new MimePart(contentType)
{
Content = new MimeContent(fs),
ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
ContentTransferEncoding = ContentEncoding.Base64,
};
var charset = "GB18030";
attachment.ContentType.Parameters.Add(charset, "name", fileName);
attachment.ContentDisposition.Parameters.Add(charset, "filename", fileName);
解决附件名字中文乱码主要依靠最后三行代码,将name和filename的字符集指定为GB18030即可。
解决文件名不能超过41字符
为什么会不超过41个字符呢?
引用github上MailKit的issue
大意是 你使用的mail client 不支持 rfc2231 编码,最有可能的是,它期望的文件名参数编码使用rfc2047编码(理论上从来没有人使用rfc2047编码参数值...,但是,哎... 有些邮件客户端就是 sucks)
然后这个回答者给出了两种解决方案,我使用了第一种如下:
var attachment = bodyBuilder.Attachments.Add (.....);
foreach (var param in attachment.ContentDisposition.Parameters)
param.EncodingMethod = ParameterEncodingMethod.Rfc2047;
foreach (var param in attachment.ContentType.Parameters)
param.EncodingMethod = ParameterEncodingMethod.Rfc2047;
第二种你可以点issue查看,完整的代码看最后
别忘了释放附件
By the way , 我还遇到了一个问题就是附件在发送之后附件使用的文件流没有被释放掉,我觉得这是个bug应该会在以后更正,不过现在你可以在添加附件是将文件流的引用收集起来,等到邮件发送之后释放掉:
List<FileStream> list = new List<FileStream>(attachments.Count());
foreach (var path in attachments)
{
if (!File.Exists(path))
{
throw new FileNotFoundException("文件未找到", path);
}
var fileName = Path.GetFileName(path);
var fileType = MimeTypes.GetMimeType(path);
var contentTypeArr = fileType.Split('/');
var contentType = new ContentType(contentTypeArr[0], contentTypeArr[1]);
MimePart attachment = null;
var fs = new FileStream(path, FileMode.Open);
list.Add(fs);
attachment = new MimePart(contentType)
{
Content = new MimeContent(fs),
ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
ContentTransferEncoding = ContentEncoding.Base64,
};
var charset = "GB18030";
attachment.ContentType.Parameters.Add(charset, "name", fileName);
attachment.ContentDisposition.Parameters.Add(charset, "filename", fileName);
foreach (var param in attachment.ContentDisposition.Parameters)
param.EncodingMethod = ParameterEncodingMethod.Rfc2047;
foreach (var param in attachment.ContentType.Parameters)
param.EncodingMethod = ParameterEncodingMethod.Rfc2047;
collection.Add(attachment);
}
await SendEmail(body, subject, isHtml, to, cc, collection);
foreach (var fs in list)
{
fs.Dispose();//手动高亮
}
Asp.Net Core MailKit 完美附件(中文名、长文件名)的更多相关文章
- Asp.Net Core 快速邮件队列设计与实现
发送邮件几乎是软件系统中必不可少的功能,在Asp.Net Core 中我们可以使用MailKit发送邮件,MailKit发送邮件比较简单,网上有许多可以参考的文章,但是应该注意附件名长度,和附件名不能 ...
- Introduction to Razor Pages in ASP.NET Core
https://docs.microsoft.com/en-us/aspnet/core/mvc/razor-pages/ 从ASP.NET Core 2.0.0版本之后,添加了新的特性Razor p ...
- Asp.Net Core采用MailKit部署到Linux Docker连接邮件服务器报错
前段时间看文章了解到发邮件的SmtpClient已经过时了,微软官方推荐大家用其他解决方案,例如MailKit. https://docs.microsoft.com/zh-cn/dotnet/api ...
- ASP.NET CORE使用MailKit的一个故障点分析
ASP.NET CORE下有需要发邮件的需求,但是原来framework下的 system.net.mail,没有实现smtpclient的功能(当时看是没有,说是准备并入.net core来着),所 ...
- Docker----与Asp.net core 的完美结合,在docker容器中创建Asp.Net Core 项目
在腾讯云上买了一个小容量的服务器,搭建一个docker环境后,可以尝试做一些单系统做起来很麻烦的东西.譬如说,你在windows OS或UbuntuOS中,突然想玩CentOS了,你可以选择将电脑再装 ...
- 用ASP.NET Core 1.0中实现邮件发送功能-阿里云邮件推送篇
在上篇中用MailKit实现了Asp.net core 邮件发送功能,但一直未解决阿里云邮件推送问题,提交工单一开始的回复不尽如人意,比如您的网络问题,您的用户名密码不正确等,但继续沟通下阿里云客户还 ...
- 又一篇Centos7下的asp.net core部署教程
历程2个多月的学习,我终于从PHP转.Net开发了. 从壹开始前后端分离[ .NETCore2.1 +Vue 2 +AOP+DI]框架 感谢老张的博客,我对asp.net core入门主要就是靠他的博 ...
- ASP.NET Core 之 Identity 入门(一)
前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OW ...
- ASP.NET Core应用针对静态文件请求的处理[3]: StaticFileMiddleware中间件如何处理针对文件请求
我们通过<以Web的形式发布静态文件>和<条件请求与区间请求>中的实例演示,以及上面针对条件请求和区间请求的介绍,从提供的功能和特性的角度对这个名为StaticFileMidd ...
随机推荐
- oracle创建函数和调用存储过程和调用函数的例子(区别)
创建函数: 格式:create or replace function func(参数 参数类型) Return number Is Begin --------业务逻辑--------- End; ...
- 十二个 ASP.NET Core 例子——IOC
目录 简单介绍 core自带IOC的实现解释 1.简单介绍 (个人理解) 是什么:IOC是一种设计原则,而非设计模式,是对流程控制,当你注入你需要的定制化类时,流程就确定了 怎么用:和IOC容器说你这 ...
- spring定时任务执行两次 项目重复初始化 项目启动两次
tomcat/config/server.xml中Host标签Context节点的问题 项目里quartz定时器总是被执行2次,通过打印发现原来项目被加载了两次,所以项目下的Listener被重复加载 ...
- github设置添加SSH
很多朋友在用github管理项目的时候,都是直接使用https url克隆到本地,当然也有有些人使用 SSH url 克隆到本地.然而,为什么绝大多数人会使用https url克隆呢? 这是因为,使用 ...
- PhpStorm (强大的PHP开发环境)2017.2.4 附注册方法
http://www.oyksoft.com/soft/40722.html?pc=1 最新版PhpStorm 2017正式版改进了PHP 7支持,改进代码完成功能. PhpStorm 是最好的PHP ...
- 利用H5构建地图和获取定位地点
地图与地理定位 定位在大部分项目中都需要实现,如何实现主要有如下的几种方法 H5定位 在HTML5中navigator有很强大的功能,其中就有定位的方法 navigator.geolocation.g ...
- vue-cli的webpack模版项目配置解析-build/dev-server.js
我们在使用vue-cli搭建vuejs项目(Vuejs实例-01使用vue-cli脚手架搭建Vue.js项目)的时候,会自动生成一系列文件,其中就包含webpack配置文件.我们现在来看下,这些配置到 ...
- Mybatis异常:java.lang.ClassNotFoundException: org.mybatis.spring.SqlSessionFactoryBean
问题描述: 一月 15, 2014 3:43:13 下午 org.springframework.context.support.AbstractApplicationContext prepareR ...
- javascript对象的标签
[[proto]]标签 [[class]]标签 [[class]] 标签,代表这对象是哪个类型的.在js中不能直接访问到.可以通过Object.prototype.toString.call(obj) ...
- Tomcat常用操作
Tomcat简介 TOMCAT是APACHE JAKARTA软件组织的一个子项目,TOMCAT是一个JSP/SERVLET容器,它是在SUN公司的JSWDK(JAVA SERVER WEB DEVEL ...