gpt4 book ai didi

c# - 在没有臃肿的第 3 方库的情况下,在 .net 中获取 imap 未读电子邮件计数

转载 作者:太空宇宙 更新时间:2023-11-03 11:15:42 25 4
gpt4 key购买 nike

背景:我们有一个用 编写的内部 Intranet 系统和 - 服务器没有 安装(在 php 中看到一些漂亮的解决方案,例如 this 但我们不能真正使用这些。) - 我们需要向我们的用户显示他们的 imap 邮箱中有多少未读电子邮件。他们的 imap 邮箱在内部托管在运行 postfix 和 dovecot imap 的 linux 机器上。

我的问题:如何通过 .net(vb 或 c#)中的 Dovecot Imap 连接到 Postfix 邮件系统并确定未读邮件的数量?

我已经尝试过的:我们使用了 Limilabs mail dll以及以下内容:

Imports System.Net.Security
Imports System
Imports Limilabs.Mail
Imports Limilabs.Client.IMAP
Imports Limilabs.Client

Function RetrieveUnread(_server, _user, _password)
Using imap As New Limilabs.Client.IMAP.Imap
'#### Handler needed because of self signed certificates
RetrieveUnread = vbNull
AddHandler imap.ServerCertificateValidate, AddressOf ValidateCertificate
imap.ConnectSSL(_server)
Try
imap.Login(_user, _password)
Catch ex As Exception
RetrieveUnread = "Failed to login"
End Try
If CStr(RetrieveUnread) <> "Failed to login" Then
imap.SelectInbox()
Dim uids As List(Of Long) = imap.Search(Flag.Unseen) 'Find all unseen messages.
'Console.WriteLine("Number of unseen messages is: " & CStr(uids.Count))
RetrieveUnread = CStr(uids.Count)
End If
imap.Close()
End Using
End Function

Private Sub ValidateCertificate(ByVal sender As Object, ByVal e As ServerCertificateValidateEventArgs)
Const ignoredErrors As SslPolicyErrors = SslPolicyErrors.RemoteCertificateChainErrors Or SslPolicyErrors.RemoteCertificateNameMismatch ' name mismatch
Dim nameOnCertificate As String = e.Certificate.Subject
If (e.SslPolicyErrors And Not ignoredErrors) = SslPolicyErrors.None Then
e.IsValid = True
Return
End If
e.IsValid = False
End Sub

然而,虽然这种方法可行,但这种方法依赖于第三方,如果许可未到位/未更新,DLL 将失败并且对于我们需要做的事情来说过于臃肿。我们只是好奇这是否可以在 native .net 代码中完成。

最佳答案

您不需要第 3 方 dll;一个简单的TcpClient会做的。

您只需将正确的 IMAP 命令发送到您的服务器,然后使用正则表达式解析结果即可。


LINQPad 就绪示例:

Sub Main()
Dim client = New System.Net.Sockets.TcpClient("hostname", 143)
Using s = client.GetStream(),
reader = New StreamReader(s),
writer = New StreamWriter(s)

Dim send As Action(Of String) = Sub(command)
writer.WriteLine(command)
writer.Flush()
End Sub

Dim recieve As Func(Of String, String) = Function(tag)
Dim response As String
Dim str As String = ""
response = reader.ReadLine()
While response IsNot Nothing
str += response
If response.StartsWith(tag, StringComparison.Ordinal) Then
Exit While
End If
response = reader.ReadLine()
End While
Return str
End Function

send("a login username password"): recieve("a")
send("b select inbox"): recieve("b")

send("b2 SEARCH UNSEEN")
Dim b2response = recieve("b2")
Dim items = Regex.Match(b2response, "SEARCH (.*) OK").Groups(1).Value.Split(" "c)
Console.WriteLine("Unread items: " + items.Count().ToString())

send("c logout"): recieve("c")
End Using
End Sub

void Main()
{
var client = new System.Net.Sockets.TcpClient("hostname", 143);
using (var s = client.GetStream())
using (var reader = new StreamReader(s))
using (var writer = new StreamWriter(s))
{
Action<string> send = (command) =>
{
writer.WriteLine(command);
writer.Flush();
};

Func<String, String> recieve = (tag) =>
{
string response;
string str="";
while ((response = reader.ReadLine()) != null )
{
str+=response;
if (response.StartsWith(tag, StringComparison.Ordinal))
break;
}
return str;
};

send("a login username password"); recieve("a");
send("b select inbox"); recieve("b");

send("b2 SEARCH UNSEEN");
var b2response = recieve("b2");
var items = Regex.Match(b2response, @"SEARCH (.*) OK").Groups[1].Value.Split(' ');
Console.WriteLine("Unread items: " + items.Count().ToString());

send("c logout"); recieve("c");
}
}

如果您想使用 SSL,您必须将流 s 包装在 SslStream 中并调用AuthenticateAsClient首先(可能使用端口 993)。

关于c# - 在没有臃肿的第 3 方库的情况下,在 .net 中获取 imap 未读电子邮件计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12724684/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com