We have been downloading Office 2003 documents stored in our database as images successfully using our ASP.NET 2.0 web portals. We recently started storing Office 2007 documents and though they upload without issue, the download and render does not work.
The file opens with the error - "The file is corrupt and cannot be opened". It is only with Office 2007 files we see this. The web server supports the Office 2007 MIME types. We also apply the correct content-type when uploading a file to the database. Sample
BinaryWrite code below. Is there something I am overlooking unique to Office 2007 files?
MyData = dreader("document")
"attachment; filename=" & dreader("file_name").ToString)
Try adding a Response.End() to make sure the server does not send and additional bytes after the file has been fully sent.
Please show the code you use to store the files?
Dim fs As FileStream
Dim st As Stream
Dim cmdInsertDocument As New System.Data.SqlClient.SqlCommand
' Read file into file stream
fs = File.Open(ViewState("file_path").ToString, FileMode.Open, FileAccess.Read)
st = fs
Dim MyData(st.Length) As Byte
st.Read(MyData, 0, st.Length)
fs = Nothing
' Set the properties of the SQL command
.CommandText = "usp_InsertTFSDocument"
.CommandType = CommandType.StoredProcedure
.Connection = conTVMR
.Parameters.Add(New System.Data.SqlClient.SqlParameter("@case_id", System.Data.SqlDbType.NVarChar, 50))
.Parameters.Add(New System.Data.SqlClient.SqlParameter("@section_id", System.Data.SqlDbType.Int, 4))
.Parameters.Add(New System.Data.SqlClient.SqlParameter("@desc", System.Data.SqlDbType.NVarChar, 50))
.Parameters.Add(New System.Data.SqlClient.SqlParameter("@file_name", System.Data.SqlDbType.NVarChar, 50))
.Parameters.Add(New System.Data.SqlClient.SqlParameter("@date_uploaded", System.Data.SqlDbType.DateTime))
.Parameters.Add(New System.Data.SqlClient.SqlParameter("@uploaded_by", System.Data.SqlDbType.Int, 4))
.Parameters.Add(New System.Data.SqlClient.SqlParameter("@document", System.Data.SqlDbType.Image))
.Parameters("@case_id").Value = Session("user").CaseID
.Parameters("@section_id").Value = CInt(cboSections.SelectedValue)
.Parameters("@desc").Value = Server.HtmlEncode(txtDocumentDesc.Text)
.Parameters("@file_name").Value = ViewState("file_name")
.Parameters("@date_uploaded").Value = Now
.Parameters("@uploaded_by").Value = Session("user").AnalystID
.Parameters("@document").Value = MyData
That's what I thought!
mbanavige was right
make sure the server does not send and additional bytes
With office 2007 files, you need to make sure that you send exactly the right amount of bytes. The problem is, that you store 1 additonal byte....
Dim MyData(st.Length) As Byte
This is the problem, you see it in most examples. But you need to realize that an array is zerobased. So if your image is 1000 bytes, you create an array of 1001 bytes (0 - 1000). The extra byte doesn't make a difference with most files, but it does with
Office 2007 files... The solution is very simple:
Dim MyData(st.Length - 1) As Byte
Also, use Response.End() instead of Response.Flush()
That should do it!
Many thx. That solved the problem. I had subtracted 1 from the image length before, but I must have done it on the download instead of the upload. Thx again.
I have reopened this thread because although the proposed solution worked fine on my local machine, it did not work when I moved the .dll files to the model office server. I confirmed that IIS 6.0 has the MIME types for the Office 2007 files, which were
added at the +Internet Information Services level. I am seeing corruption errors opening .pptx, .docx and .xlsx files save as before. Have I overlooked something else with IIS?
MIME types I'm using are:
It has nothing to do with IIS. Like I said, the amount of bytes is the problem. I'm not sure what you're trying to tell in your previoius reply, but I already said that when you store the files in the database you're storing 1 byte too much. And also, you
need to use Response.End, otherwise some additional bytes will be send also, causing the same problem.
I dashed off my last reply between meetings and so was in a hurry and failed to fully explain what was happening. My apologies.
I made the bytes length change as suggested and it worked when running the app from my dev machine. All the Office 2007 test files uploaded and downloaded without issue. Believing all was corrected I moved the app to our model office server for testing by
the user community. Once again the Office 2007 files downloaded, but threw corruption errors upon open. I double-checked the IIS MIME types just to be sure and they are fine. I am at a loss to explain why the .dll files work on my local machine, but do not
when placed on the web server.
I did not change the Response.Flush() method to Response.End as I recall that aborts the thread and throws an error. I will, however, make this change and try again.
Once again - my apologies for my earlier unclear post and many thanks for your continued support.
I did not change the Response.Flush() method to Response.End as I recall that aborts the thread and throws an error.
Try Response.Flush on your development machine? It will cause the error. Response.End will solve it....
The Response.Flush() works fine on my local machine. Using Response.Flush() on the server and I get the "file corrupted" error that started this thread. So I changed to use Response.End() and that works locally and on the server. The downside is that Response.End()
raises the thread aborted exception. The work-around for this I found - HttpContext.Current.ApplicationInstance.CompleteRequest - does not raise the exception, but the Office 2007 files throw the file corrupt error on open again.
I do believe I have spent enough time on this and will have to live with Response.End() cluttering up my my application log with thread aborted errors. Thank you again for your assistance.