发布
社区首页 >问答首页 >使用MimeKit从数据库读取时,电子邮件的丰富字符会被错误翻译

使用MimeKit从数据库读取时,电子邮件的丰富字符会被错误翻译
EN

Stack Overflow用户
提问于 2019-04-24 21:59:45
回答 1查看 175关注 0票数 1

我有一个用VB.Net编写的windows服务,它将电子邮件下载到MimeMessage对象中,删除其附件,然后将电子邮件的其余部分写入SQL Server数据库。一个单独的ASP.Net应用程序(使用VB.Net)将电子邮件读回到MimeMessage对象中,并根据请求将其返回给用户。

在此过程中发生了一些事情,导致在输出中出现奇怪的字符。

这个问题(Content encoding using MimeKit/MailKit)似乎很有希望,但将字符编码从ASCII码改为UTF8等并不能解决这个问题。

下面是将电子邮件保存到数据库的代码:

代码语言:javascript
代码运行次数:0
复制
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代码:

代码语言:javascript
代码运行次数:0
复制
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

例如,假设以下文本出现在原始电子邮件中:

代码语言:javascript
代码运行次数:0
复制
“So long and thanks for all the fish” (fancy quotes)

当回读时,它显示如下:

代码语言:javascript
代码运行次数:0
复制
†So long and thanks for all the fishâ€

其他字符替换如下:

-(长破折号)变成?欧元“

·(项目符号)变成·

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-27 00:23:48

问题出在以下代码片段中:

代码语言:javascript
代码运行次数:0
复制
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)

要修复数据损坏,您需要做的是:

代码语言:javascript
代码运行次数:0
复制
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,所以我只是猜测语法,但它应该非常接近正确)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55831902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档