尝试添加附件时,System.Mail.Net无法访问已关闭的文件异常

时间:2017-04-18 10:32:06

标签: c# asp.net-mvc system.net.mail

嗨,大家好我想给电子邮件添加一个附件,但我得到这个奇怪的例外,不清楚我做错了什么。 我从文件输入表单

获取附件
<div class="form-group">
<br/>
Select any files to attach to email
<div class="input-group">
    <label class="input-group-btn btn btn-default btn-file" id="attachFiles">
        Upload <input type="button" id="attach" name="Upload" style="display: none" value="Upload"/>
    </label>
    <label class="input-group-btn btn btn-default btn-file">
        Browse <input type="file" id="attachInput" multiple="false" style="display: none"/>
    </label>
    <input type="text" disabled="disabled" id="attachText" class="form-control input-group-addon"/>
</div>
<br/>
<ul id="issueFormAttachName" class="list-group list-inline"></ul>

然后我通过Request获取这些文件,并将它们存储在一个公共变量中,以便以后通过不同的控制器访问它们

  [HttpPost]
    [Route("home/saveAttachment")]
    public ActionResult SaveAttachment()
    {
        try
        {
            EmailAttachments = new EmailAttachments
            {
                FileCollectionBase = Request.Files
            };
            return Json("Ok");
        }
        catch (Exception ex)
        {
            return Json("Error occurred. Error details: " + ex.Message);
        }
    }

在此之后,我正在呼叫我的控制器使用此文件发送电子邮件

string usersToReceived = "";
            EmailMessage email = new EmailMessage
            {
                InnerHtmlBody = emailDto.EmailBody,
                Subject = $"Support enquiry ticket number #{issueId}",
                EmailHeader = "Thank you for contacting support"
            };
            emailDto.Users.ForEach(u => usersToReceived += u + ";");


            Dictionary<string, Stream> streams = new Dictionary<string, Stream>();

            //Check if attachments exist
            if (HomeController.EmailAttachments?.FileCollectionBase.Count > 0)
            {

                foreach (string streamName in HomeController.EmailAttachments.FileCollectionBase)
                {
                   streams.Add(streamName, HomeController.EmailAttachments.FileCollectionBase[streamName].InputStream);    
                }
                foreach (string file in HomeController.EmailAttachments.FileCollectionBase)
                {
                    //make sure stream is not disposed untill send is done
                    //Streams dont need to be explicitly disposed 
                    email.AddAttachment(streams[file], file, HomeController.EmailAttachments.FileCollectionBase[file]?.ContentType);
                }
            }

            email.Send(usersToReceived);

    }

添加附件方法只调用本机附件构造函数(New Attachment(_ms, fileName, mediaType)

现在有时当我清除我的缓存并尝试使用上面的代码时,这将有效,但大多数情况下,这将引发异常,错误无法访问封闭文件,任何人都知道这里发生了什么?我确实在最后尝试了一个清晰的缓存方法,但这不起作用

1 个答案:

答案 0 :(得分:1)

这是asp.net mvc pipeline技巧:

控制器中的每个动作都是通过反射调用的,因此,它们的管道是不同的。

当您首先Request.Files存储在您的静态变量中时 - 仅在管道未死时才可用

接下来,您调用另一个操作,请求变量不同,因此,它们不再存储Files属性。

为避免这种情况,您需要在请求之间存储数据:数据库,静态变量或类似内容。