eml带自定义信息转发功能

master
wanghaomei 2 years ago
parent cd6801faf1
commit 978601da8e

@ -1,10 +1,13 @@
using log4net;
using HtmlAgilityPack;
using log4net;
using MailSend.Common;
using MailSend.Common.Models;
using MailSend.Web.Models;
using MimeKit;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
@ -210,6 +213,330 @@ namespace MailSend.Web.Controllers
return Json(resp);
}
//转发邮件
[HttpPost]
public ActionResult Transmit()
{
var resp = new RespCommon();
//需上传eml文件
if (Request.Files.Count > 0)
{
var smtpList = mailData.MailSendSmtp.AsNoTracking()
.Select(x => x.GID)
.ToList();
var sendTo = Request.Form["SendTo"];
var ccTo = Request.Form["CcTo"];
var smtpConfig = Request.Form["SmtpConfig"]; //SmtpConfig
var mailAccount = Request.Form["MailAccount"];
var password = Request.Form["Password"];
int.TryParse(Request.Form["Port"], out int port);
var smtpServer = Request.Form["SmtpServer"];
bool.TryParse(Request.Form["SmtpSSL"], out bool smtpSSL);
var showName = Request.Form["ShowName"];
var prefixText = Request.Form["PrefixText"]; //前缀文本
if (string.IsNullOrEmpty(sendTo))
{
resp.Success = false;
resp.Code = RespCommon.RespCodeParamError;
resp.Message = "收件人不能为空";
return Json(resp);
}
//分拆收件邮箱地址
var sendToList = new List<MailboxAddress>();
var arrTo = sendTo.Replace(",", ";").Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
foreach (var item in arrTo)
{
sendToList.Add(new MailboxAddress(item, item));
}
//分拆cc邮箱地址
var ccList = new List<MailboxAddress>();
if (!string.IsNullOrEmpty(ccTo))
{
var arrCc = ccTo.Replace(",", ";").Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
foreach (var item in arrCc)
{
ccList.Add(new MailboxAddress(item, item));
}
}
MailSendSmtp smtpInfo = null;
//没有SmtpConfig参数时需要提供发件邮箱信息
if (string.IsNullOrEmpty(smtpConfig))
{
if (string.IsNullOrEmpty(mailAccount)
|| string.IsNullOrEmpty(password)
|| string.IsNullOrEmpty(smtpServer)
|| port == 0)
{
resp.Success = false;
resp.Code = RespCommon.RespCodeParamError;
resp.Message = "发件邮箱信息无效";
return Json(resp);
}
else
{
var smtpDB = mailData.MailSendSmtp.FirstOrDefault(x => x.Account == mailAccount);
if (smtpDB == null)
{
smtpDB = new MailSendSmtp();
smtpDB.GID = Guid.NewGuid().ToString();
smtpDB.Account = mailAccount;
mailData.MailSendSmtp.Add(smtpDB);
}
smtpDB.Password = password;
smtpDB.Port = port;
smtpDB.Server = smtpServer;
smtpDB.UseSSL = smtpSSL;
mailData.SaveChanges();
smtpConfig = smtpDB.GID;
smtpInfo = smtpDB;
}
}
else
{
if (!smtpList.Contains(smtpConfig))
{
resp.Success = false;
resp.Code = RespCommon.RespCodeParamError;
resp.Message = "SmtpConfig无效";
return Json(resp);
}
smtpInfo = mailData.MailSendSmtp.AsNoTracking().First(x => x.GID == smtpConfig);
}
for (var i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
if (file.ContentLength == 0)
{
resp.Success = false;
resp.Code = RespCommon.RespCodeParamError;
resp.Message = "文件内容不能为空";
return Json(resp);
}
var fileExt = Path.GetExtension(file.FileName).ToLower();
if (fileExt != ".eml")
{
resp.Success = false;
resp.Code = RespCommon.RespCodeParamError;
resp.Message = "文件格式错误";
return Json(resp);
}
MimeMessage mail = null;
try
{
mail = MimeMessage.Load(file.InputStream);
}
catch
{
resp.Success = false;
resp.Code = RespCommon.RespCodeParamError;
resp.Message = "文件格式错误";
return Json(resp);
}
if (string.IsNullOrEmpty(mail.Subject))
{
resp.Success = false;
resp.Code = RespCommon.RespCodeParamError;
resp.Message = "主题不能为空";
return Json(resp);
}
//发送人
mail.From.Clear();
mail.From.Add(new MailboxAddress(string.IsNullOrEmpty(showName) ? smtpInfo.Account : showName, smtpInfo.Account));
//收件人
mail.To.Clear();
mail.To.AddRange(sendToList);
//cc
mail.Cc.Clear();
mail.Cc.AddRange(ccList);
#region 附加前缀
var insTextList = new List<string>();
if (!string.IsNullOrEmpty(prefixText))
{
insTextList.AddRange(prefixText.Split("\r\n".ToCharArray()));
}
if (insTextList.Count > 0)
{
var textParts = mail.BodyParts.Where(x => !x.IsAttachment && x.ContentType.MediaType == "text");
if (textParts != null && textParts.Any())
{
foreach (var part in textParts)
{
var tp = part as TextPart;
var contentText = tp.Text;
Encoding srcEncoding = null;
if (!string.IsNullOrEmpty(tp.ContentType.Charset))
{
srcEncoding = Encoding.GetEncoding(tp.ContentType.Charset);
}
if (tp.ContentType.MimeType.Contains("html"))
{
HtmlDocument htmldoc = new HtmlDocument();
var htmlEncoding = htmldoc.DetectEncodingHtml(tp.Text);
htmldoc.LoadHtml(tp.Text);
var bodyNode = htmldoc.DocumentNode.SelectSingleNode("//body");
var metaLastNode = htmldoc.DocumentNode.SelectSingleNode("//meta[last()]");
var metaCharsetNode = htmldoc.DocumentNode.SelectSingleNode("//meta[contains(@http-equiv,'Content-Type')]");
Encoding toEncoding = null;
if (srcEncoding == null)
{
srcEncoding = htmldoc.DeclaredEncoding;
}
if (srcEncoding == Encoding.ASCII || srcEncoding == Encoding.GetEncoding("iso-8859-1") || srcEncoding == null)
{
toEncoding = Encoding.UTF8;
tp.ContentType.CharsetEncoding = toEncoding;
if (metaCharsetNode != null)
{
metaCharsetNode.SetAttributeValue("content", "text/html; charset=utf-8");
}
}
else
{
toEncoding = srcEncoding;
}
if (bodyNode != null)
{
var insTextReverse = new List<string>(insTextList.ToArray());
insTextReverse.Reverse();
foreach (var text in insTextReverse)
{
var insNode = htmldoc.CreateElement("p");
insNode.AppendChild(htmldoc.CreateTextNode(text));
bodyNode.InsertBefore(insNode, bodyNode.FirstChild);
}
MemoryStream ms = new MemoryStream();
htmldoc.Save(ms, toEncoding);
contentText = toEncoding.GetString(ms.ToArray());
}
else if (metaLastNode != null)
{
foreach (var text in insTextList)
{
var insNode = htmldoc.CreateElement("p");
insNode.AppendChild(htmldoc.CreateTextNode(text));
htmldoc.DocumentNode.InsertAfter(insNode, metaLastNode);
}
MemoryStream ms = new MemoryStream();
htmldoc.Save(ms, toEncoding);
contentText = toEncoding.GetString(ms.ToArray());
}
else
{
contentText = $"<p>{string.Join("</p><p>", insTextList)}</p>{contentText}";
}
tp.SetText(toEncoding, contentText);
}
else
{
Encoding toEncoding = null;
if (srcEncoding == Encoding.ASCII || srcEncoding == Encoding.GetEncoding("iso-8859-1") || srcEncoding == null)
{
toEncoding = Encoding.UTF8;
tp.ContentType.CharsetEncoding = toEncoding;
}
else
{
toEncoding = srcEncoding;
}
contentText = $"{string.Join("\r\n", insTextList)}\r\n{contentText}";
tp.SetText(toEncoding, contentText);
tp.ContentType.CharsetEncoding = toEncoding;
}
}
}
else
{
var mult = new Multipart("mixed");
var newPart = new TextPart("plain");
newPart.SetText(Encoding.UTF8, string.Join("\r\n", insTextList));
mult.Add(newPart);
mult.Add(mail.Body);
mail.Body = mult;
}
}
#endregion
var mailSend = new Common.MailSend();
mailSend.GID = Guid.NewGuid().ToString().Replace("-", "");
mailSend.SendTo = mail.To.ToString();
mailSend.CCTo = mail.Cc?.ToString();
mailSend.Title = mail.Subject;
mailSend.SmtpConfig = smtpConfig;
mailData.MailSend.Add(mailSend);
//保存eml文件
string emlFilePath = ConfigurationManager.AppSettings["EmlFilePath"];
var saveEmlPath = string.Empty;
if (string.IsNullOrEmpty(emlFilePath))
{
saveEmlPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EmlFiles");
}
else
{
saveEmlPath = Path.Combine(emlFilePath, "EmlFiles");
}
if (!Directory.Exists(saveEmlPath))
{
Directory.CreateDirectory(saveEmlPath);
}
var saveFileName = Path.Combine(saveEmlPath, $"{mailSend.GID}.eml");
mail.WriteTo(saveFileName);
mailSend.EmlFile = saveFileName; //记录eml文件位置
}
mailData.SaveChanges();
resp.Success = true;
resp.Code = RespCommon.RespCodeSuccess;
resp.Message = "提交成功";
return Json(resp);
}
else
{
resp.Success = false;
resp.Code = RespCommon.RespCodeParamError;
resp.Message = "请上传eml文件";
return Json(resp);
}
}
#region 发送记录查询
//发件记录

@ -46,12 +46,18 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="BouncyCastle.Crypto, Version=1.9.0.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL">
<HintPath>..\packages\Portable.BouncyCastle.1.9.0\lib\net40\BouncyCastle.Crypto.dll</HintPath>
</Reference>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath>
</Reference>
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll</HintPath>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.11.46.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.11.46\lib\Net45\HtmlAgilityPack.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=2.0.14.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.14\lib\net45\log4net.dll</HintPath>
</Reference>
@ -59,6 +65,9 @@
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="MimeKit, Version=3.1.0.0, Culture=neutral, PublicKeyToken=bede1c8a46c66814, processorArchitecture=MSIL">
<HintPath>..\packages\MimeKit.3.1.1\lib\net46\MimeKit.dll</HintPath>
</Reference>
<Reference Include="Quartz, Version=3.3.3.0, Culture=neutral, PublicKeyToken=f6b8c98a402cc8a4, processorArchitecture=MSIL">
<HintPath>..\packages\Quartz.3.3.3\lib\net461\Quartz.dll</HintPath>
</Reference>
@ -69,9 +78,13 @@
<HintPath>..\packages\Quartz.Plugins.3.3.3\lib\net461\Quartz.Plugins.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Remoting" />
<Reference Include="System.Security" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />

@ -15,6 +15,10 @@
<add key="webpages:Enabled" value="false"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
<!-- EML文件存放路径例如 E:\MYSHIPPING若不指定则默认使用当前web目录 -->
<add key="EmlFilePath" value="" />
</appSettings>
<connectionStrings>
<add name="MailDB" connectionString="Data Source=60.209.125.238,28000;Initial Catalog=DevMailSend;Persist Security Info=True;User ID=dev;Password=dev123" providerName="System.Data.SqlClient"/>

@ -2,6 +2,7 @@
<packages>
<package id="Antlr" version="3.5.0.2" targetFramework="net461" />
<package id="EntityFramework" version="6.4.4" targetFramework="net461" />
<package id="HtmlAgilityPack" version="1.11.46" targetFramework="net461" />
<package id="log4net" version="2.0.14" targetFramework="net461" />
<package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net461" />
<package id="Microsoft.AspNet.Mvc.zh-Hans" version="5.2.7" targetFramework="net461" />
@ -12,9 +13,12 @@
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net461" />
<package id="Microsoft.Extensions.Logging.Abstractions" version="2.1.1" targetFramework="net461" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net461" />
<package id="MimeKit" version="3.1.1" targetFramework="net461" />
<package id="Modernizr" version="2.8.3" targetFramework="net461" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net461" />
<package id="Portable.BouncyCastle" version="1.9.0" targetFramework="net461" />
<package id="Quartz" version="3.3.3" targetFramework="net461" />
<package id="Quartz.Jobs" version="3.3.3" targetFramework="net461" />
<package id="Quartz.Plugins" version="3.3.3" targetFramework="net461" />
<package id="System.Buffers" version="4.5.1" targetFramework="net461" />
</packages>
Loading…
Cancel
Save