2015-10-26 11 views
5

Khi tôi đang cố gắng gửi email có tệp đính kèm với nhiều người nhận thông qua mã C# của tôi, System.Net.Mail.SmtpException là ném câu "Không gửi thư". Ngoại lệ bên trong là "Một trong các luồng đã được sử dụng và không thể đặt lại về nguồn gốc".SMTPException Một trong các luồng đã được sử dụng và không thể đặt lại về nguồn gốc

Tôi hiểu loại lỗi này có thể xảy ra do tệp đính kèm của tôi. Tôi đã tạo ra tập tin đính kèm của tôi trong một lớp học khác nhau như -

Attatchment file; 
string fileContents = File.ReadAllText(fileName); 
file = Attachment.CreateAttachmentFromString(fileContents, fileName); 

tôi gửi nó ở định dạng này đến lớp tôi sẽ gửi email. Những điều sau xảy ra trong lớp học đó -

try 
{  
    email.Subject = subject; 
    email.Body = body; 
    if (file != null) 
    { 
     email.Attachments.Add(file); 
    } 
    _smtpClient.Send(email); 
} 
catch 
{ 
    mailSent = false; 
} 

Thư luôn được gửi đến người nhận đầu tiên nhưng không thành công cho tất cả những người còn lại. Bất kỳ ý tưởng nào tại sao điều này có thể xảy ra?

+0

Tôi đoán bạn có thể cần phải vứt bỏ 'tệp' trước khi thử sử dụng lại. – ChrisBint

+0

@ChrisBint Bạn có thể cho tôi biết lý do không? Vì lỗi này không xảy ra một cách nhất quán. Đây là lần đầu tiên nó được cắt lên. Tôi đã sử dụng nó một lúc. Tôi sẽ thử điều đó ngay bây giờ, cảm ơn bạn. – DeeDeeR

+0

@ChrisBint Tôi muốn nghiêng nhiều hơn để đoán rằng 'tệp' nội bộ có đối tượng luồng không thể được đặt lại để bắt đầu. – DavidG

Trả lời

6

Nội bộ ở lớp Attachment dường như sử dụng Stream để chứa dữ liệu. Một số loại luồng không cho phép bạn đặt lại vị trí trở lại bắt đầu và sẽ ném một số InvalidOperationException bằng thông báo bạn thấy ở trên.

giải pháp của bạn là:

  1. Gửi một email đơn nhưng đặt tất cả người nhận trong lĩnh vực Bcc.
  2. Tạo tệp đính kèm cho mỗi thư bạn gửi - không sử dụng lại cùng một đối tượng mỗi lần.
  3. Điều này có thể không hoạt động, nhưng bạn có thể thử sử dụng hàm tạo cho Attachment lấy luồng dưới dạng tham số thay vì chuỗi. Đặt tất cả dữ liệu chuỗi của bạn vào một MemoryStream cho phép định vị lại. Ví dụ:

    public Stream StringToStream(string s) 
    { 
        MemoryStream stream = new MemoryStream(); 
        StreamWriter writer = new StreamWriter(stream); 
        writer.Write(s); 
        writer.Flush(); 
        stream.Position = 0; 
        return stream; 
    } 
    

    Sau đó này:

    var stream = StringToStream(File.ReadAllText(fileName)); 
    Attatchment file = new Attachment(stream, fileName); 
    

Lưu ý: Bạn đang initialising các đối tượng tập tin đính kèm không chính xác. Trong số constructor có hai tham số string, tham số thứ hai là loại phương tiện chứ không phải tên tệp.

+0

Oh. Có cách nào chúng ta có thể đặt tên của tệp trong phần đính kèm không? Hầu hết các trực tuyến giúp dường như đề nghị thiết lập các tài sản tên mà thực sự là loại nội dung MIME. – DeeDeeR

+0

Có, thuộc tính tên là những gì bạn nên sử dụng. – DavidG

Các vấn đề liên quan