SMTPException 其中一个流已被使用,无法重置为原点
SMTPException One of the streams has already been used and can't be reset to the origin
当我尝试通过我的 C# 代码向多个收件人发送一封带有附件的电子邮件时,抛出一个 System.Net.Mail.SmtpException 说 "Failure sending mail."
内部异常是 "One of the streams has already been used and can't be reset to the origin."
我理解这种错误可能是我的执着造成的。
我在不同的 class 中创建了我的附件,如 -
Attatchment file;
string fileContents = File.ReadAllText(fileName);
file = Attachment.CreateAttachmentFromString(fileContents, fileName);
我将以这种格式将其发送到发送电子邮件的 class。 class -
中发生以下情况
try
{
email.Subject = subject;
email.Body = body;
if (file != null)
{
email.Attachments.Add(file);
}
_smtpClient.Send(email);
}
catch
{
mailSent = false;
}
邮件总是发送给第一个收件人,但对其余所有收件人均失败。
知道为什么会发生这种情况吗?
在 Attachment
class 内部,它似乎使用 Stream
来包含数据。某些类型的流不允许您将位置重置回开始位置,并且会抛出一个 InvalidOperationException
以及您在上面看到的消息。
您的解决方案是:
- 发送一封邮件,但将所有收件人放在
Bcc
字段中。
- 为您发送的每封邮件创建附件 - 不要每次都重复使用相同的对象。
这可能行不通,但您可以尝试使用 Attachment
的构造函数,它将流而不是字符串作为参数。将所有字符串数据放入允许重新定位的 MemoryStream
中。例如:
public Stream StringToStream(string s)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
然后这个:
var stream = StringToStream(File.ReadAllText(fileName));
Attatchment file = new Attachment(stream, fileName);
注意:您错误地初始化了附件对象。在带有两个 string
参数的 constructor 中,第二个参数是媒体类型,而不是文件名。
在我们的例子中,它是 LinkedResource
实例(文件附件,作为内联图像嵌入到电子邮件中)被重复用于多条消息。消息在发送后 .Dispose
' - 这关闭了所有底层流。
我想这基本上可以归结为@DavidG 的回答,只需加上我的两分钱 - 请记住检查嵌入式资源,而不仅仅是普通附件。
当我尝试通过我的 C# 代码向多个收件人发送一封带有附件的电子邮件时,抛出一个 System.Net.Mail.SmtpException 说 "Failure sending mail." 内部异常是 "One of the streams has already been used and can't be reset to the origin."
我理解这种错误可能是我的执着造成的。 我在不同的 class 中创建了我的附件,如 -
Attatchment file;
string fileContents = File.ReadAllText(fileName);
file = Attachment.CreateAttachmentFromString(fileContents, fileName);
我将以这种格式将其发送到发送电子邮件的 class。 class -
中发生以下情况try
{
email.Subject = subject;
email.Body = body;
if (file != null)
{
email.Attachments.Add(file);
}
_smtpClient.Send(email);
}
catch
{
mailSent = false;
}
邮件总是发送给第一个收件人,但对其余所有收件人均失败。 知道为什么会发生这种情况吗?
在 Attachment
class 内部,它似乎使用 Stream
来包含数据。某些类型的流不允许您将位置重置回开始位置,并且会抛出一个 InvalidOperationException
以及您在上面看到的消息。
您的解决方案是:
- 发送一封邮件,但将所有收件人放在
Bcc
字段中。 - 为您发送的每封邮件创建附件 - 不要每次都重复使用相同的对象。
这可能行不通,但您可以尝试使用
Attachment
的构造函数,它将流而不是字符串作为参数。将所有字符串数据放入允许重新定位的MemoryStream
中。例如:public Stream StringToStream(string s) { MemoryStream stream = new MemoryStream(); StreamWriter writer = new StreamWriter(stream); writer.Write(s); writer.Flush(); stream.Position = 0; return stream; }
然后这个:
var stream = StringToStream(File.ReadAllText(fileName)); Attatchment file = new Attachment(stream, fileName);
注意:您错误地初始化了附件对象。在带有两个 string
参数的 constructor 中,第二个参数是媒体类型,而不是文件名。
在我们的例子中,它是 LinkedResource
实例(文件附件,作为内联图像嵌入到电子邮件中)被重复用于多条消息。消息在发送后 .Dispose
' - 这关闭了所有底层流。
我想这基本上可以归结为@DavidG 的回答,只需加上我的两分钱 - 请记住检查嵌入式资源,而不仅仅是普通附件。