asp.net - 使用 MimeKit 从数据库读取时,电子邮件的富字符被错误翻译
问题描述
我有一个用 VB.Net 编写的 Windows 服务,它将电子邮件下载到 MimeMessage 对象中,删除它们的附件,然后将电子邮件的剩余部分写入 SQL Server 数据库。一个单独的 ASP.Net 应用程序(使用 VB.Net)将电子邮件读回 MimeMessage 对象,并根据请求将其返回给用户。
在此过程中发生了一些事情,导致输出中出现奇怪的字符。
这个问题(使用 MimeKit/MailKit 进行内容编码)似乎很有希望,但是将字符编码从 ASCII 更改为 UTF8 等并没有解决它。
以下是将电子邮件保存到数据库的代码:
Sub ImportEmail(exConnectionString As String)
Dim oClient As New Pop3Client()
' … email connection code removed …
Dim message = oClient.GetMessage(0)
Dim strippedMessage As MimeMessage = message
' … code to remove attachments removed …
Dim mem As New MemoryStream
strippedMessage.WriteTo(mem)
Dim bytes = mem.ToArray
Dim con As New SqlConnection(exConnectionString)
con.Open()
Dim com As New SqlCommand("INSERT INTO Emails (Body) VALUES (@RawDocument)", con)
com.CommandType = CommandType.Text
com.Parameters.AddWithValue("@RawDocument", bytes)
com.ExecuteNonQuery()
con.Close()
End Sub
这是用于将其读回给用户的 ASP.Net 代码:
Private Sub OutputEmail(exConnectionString As String)
Dim BlobString As String = ""
Dim Sql As String = "SELECT Body FROM Emails WHERE Id = @id"
Dim com As New SqlClient.SqlCommand(Sql)
com.CommandType = CommandType.Text
com.Parameters.AddWithValue("@id", ViewState("email_id"))
Dim con As New SqlConnection(exConnectionString)
con.Open()
com.Connection = con
Dim da As New SqlClient.SqlDataAdapter(com)
Dim dt As New DataTable()
da.Fill(dt)
con.Close()
If dt.Rows.Count > 0 Then
Dim Row = dt.Rows(0)
BlobString = Row(0).ToString()
Dim MemStream As MemoryStream = GetMemoryStreamFromASCIIEncodedString(BlobString)
Dim message As MimeMessage = MimeMessage.Load(MemStream)
BodyBuilder.HtmlBody = message.HtmlBody
BodyBuilder.TextBody = message.TextBody
message.Body = BodyBuilder.ToMessageBody()
Response.ContentType = "message/rfc822"
Response.AddHeader("Content-Disposition", "attachment;filename=""" & Left(message.Subject, 35) & ".eml""")
Response.Write(message)
Response.End()
End If
End Sub
Private Function GetMemoryStreamFromASCIIEncodedString(ByVal BlobString As String) As MemoryStream
Dim BlobStream As Byte() = Encoding.ASCII.GetBytes(BlobString) ' **
Dim MemStream As MemoryStream = New MemoryStream()
MemStream.Write(BlobStream, 0, BlobStream.Length)
MemStream.Position = 0
Return MemStream
End Function
例如,假设以下文本出现在原始电子邮件中:
“So long and thanks for all the fish” (fancy quotes)
回读时,显示如下:
†So long and thanks for all the fishâ€
其他字符替换如下:
– (长破折号)变为 ¢€“</p>
•(子弹)变成•</p>
解决方案
问题在于以下代码段:
If dt.Rows.Count > 0 Then
Dim Row = dt.Rows(0)
BlobString = Row(0).ToString() ' <-- the ToString() is the problem
Dim MemStream As MemoryStream = GetMemoryStreamFromASCIIEncodedString(BlobString)
Dim message As MimeMessage = MimeMessage.Load(MemStream)
要修复数据损坏,您需要做的是:
If dt.Rows.Count > 0 Then
Dim Row = dt.Rows(0)
Dim BlobString as Byte() = Row(0)
Dim MemStream As MemoryStream = new MemoryStream (BlobString, False)
Dim message As MimeMessage = MimeMessage.Load(MemStream)
你也可以摆脱你的GetMemoryStreamFromASCIIEncodedString
功能。
(注意:我不知道 VB.NET,所以我只是猜测语法,但应该非常接近正确)
推荐阅读
- java - 如何在 JAVA 中使用 seedBytes 使 SecureRandom 保持不变?
- excel - EXCEL VBA - 自动插入代码宏,这甚至可能吗?
- spring-boot - 来自 Springboot 应用程序的 Redis 缓存配置设置
- javascript - Slick Carousel 插件 - 自定义点
- python - 字母汤 - 确定您是否可以用汤碗中的字母写下您的信息
- graphql - getStaticPaths 不适用于 Next.js 中的此 API 请求
- python - 无法连接到 Python/Gmail API
- css - ExtJS Classic 7.3.0:使用 .scss 文件设计应用程序视图
- api - Facebook Graph API 给出的 ID 与 Profile ID 不同
- node.js - 为什么我的单元测试显示一个页面没有被渲染,而它显然已经被渲染了?