By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,007 Members | 1,059 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,007 IT Pros & Developers. It's quick & easy.

Problems storing upload file in session (ObjectDisposedException)

P: n/a
Hi

I have the following code. I upload an XML file using the FileUpload object,
store the stream in a session so the user gets the chance to confirm some
options then pass the stream from the Session to an XmlReader.

if (performImport == false)
{
Session["__xmlImportFile"] = fileUpload1.FileContent;
//... some other code
}
else
{
if (Session["__xmlImportFile"] != null)
{
Stream xmlFile = (Stream)Session["__xmlImportFile"];
xmlFile.Position = 0;
// ... pass xmlFile to XmlReader
}
Session.Remove("__xmlImportFile");
}

This works fine on the Visual Studio web server. When I transfer the code to
an IIS web server I can only get the code to work if the uploaded file is
80Kb or less. Anything over that and I get an ObjectDisposedException
(Cannot access a closed file.) The size in bytes of the stream from the
session appears to be correct before the XmlReader is called.

[ObjectDisposedException: Cannot access a closed file.]
System.IO.__Error.FileNotOpen() +56
System.IO.FileStream.Seek(Int64 offset, SeekOrigin origin) +1945963
System.Web.TempFile.GetBytes(Int32 offset, Int32 length, Byte[] buffer,
Int32 bufferOffset) +35
System.Web.HttpRawUploadedContent.CopyBytes(Int32 offset, Byte[] buffer,
Int32 bufferOffset, Int32 length) +112
System.Web.HttpInputStream.Read(Byte[] buffer, Int32 offset, Int32 count)
+47
System.Xml.XmlTextReaderImpl.InitStreamInput(Uri baseUri, String
baseUriStr, Stream stream, Byte[] bytes, Int32 byteCount, Encoding encoding)
+196
System.Xml.XmlTextReaderImpl..ctor(Stream stream, Byte[] bytes, Int32
byteCount, XmlReaderSettings settings, Uri baseUri, String baseUriStr,
XmlParserContext context, Boolean closeInput) +62
System.Xml.XmlReader.CreateReaderImpl(Stream input, XmlReaderSettings
settings, Uri baseUri, String baseUriStr, XmlParserContext inputContext,
Boolean closeInput) +68
System.Xml.XmlReader.Create(Stream input, XmlReaderSettings settings,
String baseUri) +37
System.Xml.XmlReader.Create(Stream input, XmlReaderSettings settings) +30

Can you tell me what is happening here and how I might resolve it?

Many thanks
Andrew
Jul 19 '07 #1
Share this Question
Share on Google+
6 Replies


P: n/a
J055 wrote:
Hi

I have the following code. I upload an XML file using the FileUpload object,
store the stream in a session so the user gets the chance to confirm some
options then pass the stream from the Session to an XmlReader.

if (performImport == false)
{
Session["__xmlImportFile"] = fileUpload1.FileContent;
As you haven't created the stream yourself, you don't have control over
when the stream is disposed. When the FileUpload control is disposed, it
also disposes the stream.

If you need to store something in a session variable, you have to store
the actual content of the file, not the stream used to read it.

Generally it's a bad idea to store large objects in session variables,
though. It uses up memory, and that is a limited resource on the server.
You should consider other options for storing it.
//... some other code
}
else
{
if (Session["__xmlImportFile"] != null)
{
Stream xmlFile = (Stream)Session["__xmlImportFile"];
xmlFile.Position = 0;
// ... pass xmlFile to XmlReader
}
Session.Remove("__xmlImportFile");
}

This works fine on the Visual Studio web server.
No, not fine. You just got lucky (?) that it didn't blow up.
When I transfer the code to
an IIS web server I can only get the code to work if the uploaded file is
80Kb or less. Anything over that and I get an ObjectDisposedException
(Cannot access a closed file.) The size in bytes of the stream from the
session appears to be correct before the XmlReader is called.

[ObjectDisposedException: Cannot access a closed file.]
System.IO.__Error.FileNotOpen() +56
System.IO.FileStream.Seek(Int64 offset, SeekOrigin origin) +1945963
System.Web.TempFile.GetBytes(Int32 offset, Int32 length, Byte[] buffer,
Int32 bufferOffset) +35
System.Web.HttpRawUploadedContent.CopyBytes(Int32 offset, Byte[] buffer,
Int32 bufferOffset, Int32 length) +112
System.Web.HttpInputStream.Read(Byte[] buffer, Int32 offset, Int32 count)
+47
System.Xml.XmlTextReaderImpl.InitStreamInput(Uri baseUri, String
baseUriStr, Stream stream, Byte[] bytes, Int32 byteCount, Encoding encoding)
+196
System.Xml.XmlTextReaderImpl..ctor(Stream stream, Byte[] bytes, Int32
byteCount, XmlReaderSettings settings, Uri baseUri, String baseUriStr,
XmlParserContext context, Boolean closeInput) +62
System.Xml.XmlReader.CreateReaderImpl(Stream input, XmlReaderSettings
settings, Uri baseUri, String baseUriStr, XmlParserContext inputContext,
Boolean closeInput) +68
System.Xml.XmlReader.Create(Stream input, XmlReaderSettings settings,
String baseUri) +37
System.Xml.XmlReader.Create(Stream input, XmlReaderSettings settings) +30

Can you tell me what is happening here and how I might resolve it?

Many thanks
Andrew
--
Göran Andersson
_____
http://www.guffa.com
Jul 19 '07 #2

P: n/a
As Goran indicated, you might want to try this approach, which stores the
contents (that's what you want anyway, right?):

Int32 fileLen;
// Get the length of the file.
fileLen = FileUpload1.PostedFile.ContentLength;
// Create a byte array to hold the contents of the file.
Byte[] Input = new Byte[fileLen];
// Initialize the stream to read the uploaded file.
myStream = FileUpload1.FileContent;
// Read the file into the byte array.
myStream.Read(Input, 0, fileLen);
// Store the byte array in Session
Session["__xmlImportFileBytes"] = Input;

--Peter
Recursion: see Recursion
site: http://www.eggheadcafe.com
unBlog: http://petesbloggerama.blogspot.com
bogMetaFinder: http://www.blogmetafinder.com

"J055" wrote:
Hi

I have the following code. I upload an XML file using the FileUpload object,
store the stream in a session so the user gets the chance to confirm some
options then pass the stream from the Session to an XmlReader.

if (performImport == false)
{
Session["__xmlImportFile"] = fileUpload1.FileContent;
//... some other code
}
else
{
if (Session["__xmlImportFile"] != null)
{
Stream xmlFile = (Stream)Session["__xmlImportFile"];
xmlFile.Position = 0;
// ... pass xmlFile to XmlReader
}
Session.Remove("__xmlImportFile");
}

This works fine on the Visual Studio web server. When I transfer the code to
an IIS web server I can only get the code to work if the uploaded file is
80Kb or less. Anything over that and I get an ObjectDisposedException
(Cannot access a closed file.) The size in bytes of the stream from the
session appears to be correct before the XmlReader is called.

[ObjectDisposedException: Cannot access a closed file.]
System.IO.__Error.FileNotOpen() +56
System.IO.FileStream.Seek(Int64 offset, SeekOrigin origin) +1945963
System.Web.TempFile.GetBytes(Int32 offset, Int32 length, Byte[] buffer,
Int32 bufferOffset) +35
System.Web.HttpRawUploadedContent.CopyBytes(Int32 offset, Byte[] buffer,
Int32 bufferOffset, Int32 length) +112
System.Web.HttpInputStream.Read(Byte[] buffer, Int32 offset, Int32 count)
+47
System.Xml.XmlTextReaderImpl.InitStreamInput(Uri baseUri, String
baseUriStr, Stream stream, Byte[] bytes, Int32 byteCount, Encoding encoding)
+196
System.Xml.XmlTextReaderImpl..ctor(Stream stream, Byte[] bytes, Int32
byteCount, XmlReaderSettings settings, Uri baseUri, String baseUriStr,
XmlParserContext context, Boolean closeInput) +62
System.Xml.XmlReader.CreateReaderImpl(Stream input, XmlReaderSettings
settings, Uri baseUri, String baseUriStr, XmlParserContext inputContext,
Boolean closeInput) +68
System.Xml.XmlReader.Create(Stream input, XmlReaderSettings settings,
String baseUri) +37
System.Xml.XmlReader.Create(Stream input, XmlReaderSettings settings) +30

Can you tell me what is happening here and how I might resolve it?

Many thanks
Andrew
Jul 19 '07 #3

P: n/a
when the request completes, the stream is closed, so storing in session
is useless. if small, you could read the stream into sring, or into a
dom and store in session

-- bruce (sqlwork.com)

J055 wrote:
Hi

I have the following code. I upload an XML file using the FileUpload object,
store the stream in a session so the user gets the chance to confirm some
options then pass the stream from the Session to an XmlReader.

if (performImport == false)
{
Session["__xmlImportFile"] = fileUpload1.FileContent;
//... some other code
}
else
{
if (Session["__xmlImportFile"] != null)
{
Stream xmlFile = (Stream)Session["__xmlImportFile"];
xmlFile.Position = 0;
// ... pass xmlFile to XmlReader
}
Session.Remove("__xmlImportFile");
}

This works fine on the Visual Studio web server. When I transfer the code to
an IIS web server I can only get the code to work if the uploaded file is
80Kb or less. Anything over that and I get an ObjectDisposedException
(Cannot access a closed file.) The size in bytes of the stream from the
session appears to be correct before the XmlReader is called.

[ObjectDisposedException: Cannot access a closed file.]
System.IO.__Error.FileNotOpen() +56
System.IO.FileStream.Seek(Int64 offset, SeekOrigin origin) +1945963
System.Web.TempFile.GetBytes(Int32 offset, Int32 length, Byte[] buffer,
Int32 bufferOffset) +35
System.Web.HttpRawUploadedContent.CopyBytes(Int32 offset, Byte[] buffer,
Int32 bufferOffset, Int32 length) +112
System.Web.HttpInputStream.Read(Byte[] buffer, Int32 offset, Int32 count)
+47
System.Xml.XmlTextReaderImpl.InitStreamInput(Uri baseUri, String
baseUriStr, Stream stream, Byte[] bytes, Int32 byteCount, Encoding encoding)
+196
System.Xml.XmlTextReaderImpl..ctor(Stream stream, Byte[] bytes, Int32
byteCount, XmlReaderSettings settings, Uri baseUri, String baseUriStr,
XmlParserContext context, Boolean closeInput) +62
System.Xml.XmlReader.CreateReaderImpl(Stream input, XmlReaderSettings
settings, Uri baseUri, String baseUriStr, XmlParserContext inputContext,
Boolean closeInput) +68
System.Xml.XmlReader.Create(Stream input, XmlReaderSettings settings,
String baseUri) +37
System.Xml.XmlReader.Create(Stream input, XmlReaderSettings settings) +30

Can you tell me what is happening here and how I might resolve it?

Many thanks
Andrew

Jul 19 '07 #4

P: n/a
Peter Bromberg [C# MVP] wrote:
As Goran indicated, you might want to try this approach, which stores the
contents (that's what you want anyway, right?):

Int32 fileLen;
// Get the length of the file.
fileLen = FileUpload1.PostedFile.ContentLength;
// Create a byte array to hold the contents of the file.
Byte[] Input = new Byte[fileLen];
// Initialize the stream to read the uploaded file.
myStream = FileUpload1.FileContent;
// Read the file into the byte array.
myStream.Read(Input, 0, fileLen);
Oops! ;)

The Read method returns the actual number of bytes read, which may be
less than the number of bytes requested. You have to loop until you have
read all the bytes, i.e. until Read returns zero.
// Store the byte array in Session
Session["__xmlImportFileBytes"] = Input;

--Peter
Recursion: see Recursion
site: http://www.eggheadcafe.com
unBlog: http://petesbloggerama.blogspot.com
bogMetaFinder: http://www.blogmetafinder.com
--
Göran Andersson
_____
http://www.guffa.com
Jul 19 '07 #5

P: n/a
Hi Andrew,

As other members have mentioned, storing the Stream object directly in
Session is not a safe approach as you can not predict or confirm when the
stream will be closed or disposed. And the behavior vary much between VS
2005 web test server and IIS hosting context. For your scenario, you can
consider the following approachs:

1. Read out the actual binary content(byte array) from the stream and store
the binary content into session state. However, as others have said, this
is not quite a good way since it will cause session state memory
pressure(when there is many large files stored at the same time).

2. You can consider save uploaded file into a temp dir(in a temp file). And
in the session state, you simply store the path and file name of the temp
file.

How do you think?

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead
This posting is provided "AS IS" with no warranties, and confers no rights.


Jul 20 '07 #6

P: n/a
Hi

Thanks to everyone for there assistance. It makes sense to me now about the
stream being disposed of outside my control. The reason I thought it OK to
store a stream in a Session is simply because it's is a very occasional
demand on the system for our application.

I've decided to store the file on disk, however. I found the
Path.GetTempFileName method very useful for this.

Many thanks
Andrew
"Steven Cheng[MSFT]" <st*****@online.microsoft.comwrote in message
news:oT**************@TK2MSFTNGHUB02.phx.gbl...
Hi Andrew,

As other members have mentioned, storing the Stream object directly in
Session is not a safe approach as you can not predict or confirm when the
stream will be closed or disposed. And the behavior vary much between VS
2005 web test server and IIS hosting context. For your scenario, you can
consider the following approachs:

1. Read out the actual binary content(byte array) from the stream and
store
the binary content into session state. However, as others have said, this
is not quite a good way since it will cause session state memory
pressure(when there is many large files stored at the same time).

2. You can consider save uploaded file into a temp dir(in a temp file).
And
in the session state, you simply store the path and file name of the temp
file.

How do you think?

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead
This posting is provided "AS IS" with no warranties, and confers no
rights.


Jul 23 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.