2

現在、ユーザーがいくつかのフィールドに入力してファイルを添付するためのフォームを MVC3 で提供しています。投稿の際、投稿された情報(添付ファイル付き)を 2 回送信します。

私が抱えている問題は、最初の電子メールが正しい添付ファイルで正常に送信されることです。2 番目の電子メールは、サイズが 0 のファイルが添付されて送信されます。ファイルのアップロードから添付オブジェクトを作成した後、それを再利用できないようです。デバッガーを使用すると、ファイル アップロード オブジェクトがまだメモリ内にあることがわかりますが、その ContentLength は 0 になります。

したがって、次の例で、コードを次のように単純化すると:

public static void SendDummyEmail1()
{
    using (var mailMessage = new MailMessage("from@email.com", "to@email.com"))
    {
        mailMessage.Subject = "Email Subject"
        mailMessage.Body = Razor.Parse(template, (dynamic)dynamicTokens);
        mailMessage.IsBodyHtml = true;

        if (_fileUpload != null && _fileUpload.ContentLength > 0)
        {
            var attachment = new Attachment(_fileUpload.InputStream, _fileUpload.FileName, MediaTypeNames.Application.Octet);
            attachment.ContentDisposition.FileName = Path.GetFileName(_fileUpload.FileName);
            mailMessage.Attachments.Add(attachment);
        }

        SendMail(mailMessage);
    }
}

public static void SendMail(MailMessage message)
{
    var client = new SmtpClient
    {
        Host = ConfigurationManager.AppSettings[SmtpHostname],
        Port = Convert.ToInt32(ConfigurationManager.AppSettings[SmtpPortNumber]),
        UseDefaultCredentials = true,
        Credentials = CredentialCache.DefaultNetworkCredentials,
        DeliveryMethod = SmtpDeliveryMethod.Network,
        EnableSsl = true,  
    };

    // Work around remote certificate validation
    // Ref: http://stackoverflow.com/questions/777607/the-remote-certificate-is-invalid-according-to-the-validation-procedure-using
    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

    client.Send(message);
}

上記のメソッドを 2 回続けて呼び出すと、最初のメールは正常に送信されます。2 番目の電子メールは送信されますが、ContentLength が 0 になるため、添付ファイルはありません。

SendDummyEmail1();
SendDummyEmail1();
4

3 に答える 3

3

_fileUpload.InputStream.CanSeekあなたの場合はに等しいと思いますfalse。つまり、それを再び巻き上げて(Position = 0)、そこから読み取ることはできません。アップロードしたファイルストリームを最初にメモリストリームにコピーしてから、次のように初期ストリームの代わりに使用してみてください。

MemoryStream ms = new MemoryStream();
_fileUpload.InputStream.CopyTo(ms);
byte[] data = ms.ToArray();
SendDummyEmail1(data);
SendDummyEmail1(data);

public static void SendDummyEmail1(byte[] fileContent)
{
 ...
 var attachment = new Attachment(new MemoryStream(fileContent), ...
}
于 2013-02-28T10:42:07.617 に答える
3

_fileUpload ではなく、メモリ ストリームをインスタンス変数として使用します。次に、それを各メールの新しいストリームに複製します (したがって、複数のコンシューマーはありません)。添付ファイルの読み取りが最初から開始されるように、書き込み後にストリームをリセットすることを忘れないでください。

于 2013-02-28T10:56:14.590 に答える
0

アップロードしたファイルをサーバーに保存し、添付ファイルのファイルパスを使用します。

var attachment = new Attachment(filePath, MediaTypeNames.Application.Octet);

メール送信後、必要に応じてアップロードしたファイルを削除してください。

于 2013-02-28T10:10:40.617 に答える