I have a website which requires a web form with multiple uploads which get emailed to someone.
To fix this we've created a temporary file-stream which basically copies the upload to the file-system and removes the file when disposed.
The TemporaryFileStream inherits the Stream object to trick dotnet into thinking it actually is a stream, that way we can use var attachment = new Attachment(fileStream, file.FileName, file.ContentType);
for the emails.
The problem I'm having is that when the file is larger than 10 MB or if the total of the Files is larger than 10 MB I get a System.IO Error saying you cannot access a closed file.
I don't understand why this only happens when the size is larger than 10 MB, it's not the upload because the HttpPostedFileBase gets send correctly, the error occurs when actually calling the `Read()' method on the temporary filestream.
This is how the temporary file stream is initiated:
/// <summary>
/// A temporary fileStream that is removed when disposed
/// </summary>
/// <param name="file">The HttpPosted file to write to the temp directory</param>
public TemporaryFileStream(HttpPostedFileBase file)
{
file.InputStream.Flush();
file.InputStream.Position = 0;
_tempPath = Path.Combine(Path.GetTempPath(), String.Join(".", Path.GetRandomFileName(), file.FileName));
_innerStream = File.Create(_tempPath);
file.InputStream.CopyTo(_innerStream);
_innerStream.Flush(true);
_innerStream.Position = 0;
_innerStream.Unlock(0,_innerStream.Length);
}
The http input stream is copied to the temp folder instantly and read later.
After sending the mail, the dispose()
method is called by code not by using a using()
wrapper.
public new void Dispose()
{
if (!_baseDisposed)
{
_baseDisposed = true;
Close();
base.Dispose();
}
if (!_innerDisposed)
{
_innerDisposed = true;
_innerStream.Flush();
_innerStream.Close();
_innerStream.Dispose();
}
if (File.Exists(_tempPath))
File.Delete(_tempPath);
}
This is the only place where Close()
is called but it gets called after sending the mail.
I'm pretty sure it's not the httpRuntime.maxRequestLength setting because we've set that to: "512000".
I've even tried the following without success:
httpRuntime maxRequestLength="512000" executionTimeout="3600"
appRequestQueueLimit="100" requestLengthDiskThreshold="10024000"
enableKernelOutputCache="false" relaxedUrlToFileSystemMapping="true" />
Is there any reason why my filestream can be closed outside of my controll? Or could the async context of the SendMail(...).ConfigureAsync(true)
have something to do with this?
With kind regards, Marvin Brouwer.