Very odd problem as this is working perfectly on our old Classic ASP site. We are basically querying the database and exporting around 2200 lines of text to a Text File through Response.Write to be output to a dialog box and allows the user to save the file.
Response.Clear()
Response.ClearContent()
Response.ClearHeaders()
Dim fileName As String = "TECH" & test & ".txt"
Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", fileName))
Response.ContentType = "text/plain"
Response.Write(strHeader)
Dim sw As New IO.StringWriter()
Dim dtRow As DataRow
For Each dtRow In dt3.Rows
sw.Write(dtRow.Item("RECORD") & vbCrLf)
Next
Response.Write(sw.ToString)
Response.Write(strTrailer & intRecCount)
Response.End()
I can either use StringWriter or simply use Response.Write(dt.Rows(i).Item("RECORD").toString
Either way, the Export is causing a horrendous hang on our development site. My local machine causes no hang and is almost instantaneous. The recordset isn't very large, and the lines it is writing are small.
Anyone have any idea why this would be hanging? It does EVENTUALLY allow for a save and display the file, but it's well over 3-4 minutes.
Attach a remote debugger and find where its hanging?
You need to figure out if its the string writer loop, or the actual query code (which is not provided here).
Sounds like maybe you're overflowing the output buffer. Perhaps add a counter in there to flush every few hundred lines.
Also, the Response object basically does most of the work for a StringWriter for you. Using the StringWriter as an intermediary is probably redundant.
Both using StringWriter and DataTable are overkill.
Why not use directly SqlReader to get the results from the database, and while reading the reader, write directly to the output stream? Much faster, and much less memory consumed.
As an answer to your second question - why the ASP was working OK, I doubt that there you have stored the same content 3 times in memory in order to output it (in the DataTable, in the StringWriter and in the output buffer). My ASP is a little bit rusty, but I would guess that there you are using database reader of some sort.
Also, better employ some logging infrastructure (NLog, log4net), so you can output some timing about which operation delays how much, as an alternative to attaching a remote debugger.
Related
I am making a Post request and receiving the response from an end point, through which i receive the excel content.
I have used this end point before and tried binding a email worker, which works fine. (Conforming end point response is clear).
Now with a different requirement, i need to make the post call to this end point and download the excel file.xlsx file hence generated is corrupted and i excel tries to recover it once the file is downloaded.
Have gone thorugh different threads and tried almost everything.
Nothing seems to work.
try 1:
Response.Clear();
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName.Replace("\"", String.Empty));
And while debugging i have made sure to close the response. (Response.End()).
Have even added the explicit headers
Response.AddHeader("content-disposition", "attachment; filename=\"" fileName".xlsx\"");
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Try 2
have explicity written the memoryStream to the response.
Response.BinaryWrite(tgtBytes);
Have ensured Response.Clear before writing to response and making sure of memoryStream.dispose and Response.End.
Have even used. Response.ClearHeaders().
Try - 3.
Instead of MemoryStream, tried with filestream, saving in a file and downloading from the File written. Problem still Persists.
I am getting a binaryStream as response and no encoding in done as it isn't hex value.
Either the stream is corrupted ( which is likely not the case, as i use the end point for different requirements) or the response is corrupted.
how should i check what is the exact cause ??
Please Let me know what else can i try.
I am having some difficulties exporting excel file using NPOI dll through ASP.NET page.
Basically, I am able to populate the cells with no exception, however right at the few last steps where I need to export out the excel, it throws an exception when it tries to run Response.End.
Dim ms As New MemoryStream
xlWorkbook.Write(ms)
Response.ContentType = "application/vnd.ms-excel"
Response.AddHeader("content-disposition", "attachment;filename=M4_Control_Chart.xls")
Response.Clear()
Response.BinaryWrite(ms.GetBuffer())
Response.End()
I dont get a lot of information from the exception, it just says "Unable to evaluate expression"
Does anyone have any idea how to fix this?
Thanks.
Flush your stream before you read the buffer: ms.Flush()
I have to make an ASP.net form and only need to gather 3 fields: name, bday and email.
Do you think it's best to write the info to a csv or xml file, or do you think it's worth it to write to a SQL DB or something and then export from there to a file?
I'm of the opinion that just writing to a flat file is best because it's just going to need to be exported into a csv/xml file anyway so it can be appended to an excel file.
I'd use something like streamwriter or filestream in my C# submitbutton function:
StreamWriter sw = new StreamWriter(filename, true);
sw.WriteLine(string.Concat
( textBox1.Text
, textBox2.Text
, textBox3.Text
, textBox4.Text
, textBox5.Text
, textBox6.Text
, textBox7.Text ));
sw.Close();
Am I overlooking shortcomings of using csv and StreamWriter? Like do any weird things happen when the file gets to a certain size?
Also, how is Streamwriter compared to Filestream, or should I be looking at a different method entirely?
Even for small applications you will never regret using a database. Especially if they ever change / grow. Text files are a lot harder to make a change if you want to store other data.
File access for web applications be challenging at best. If you do use a Database I would ultimately look in to XML/XSD and using Data Sets.
I'm currently patching an asp.net program where I need to be able to send an image to an SQL Server 2005 DB. It works fine when I use the asp:fileupload control, but the trick is that when the user deletes the image, I'm supposed to replace it with an image from the server saying "empty", in code-behind.
I know how to open, use and save text files in vb, but I can't find any information anywhere on how to open an image / binary file in a similar manner so that I can use it as an sql-parameter on the update query.
Below is an example of how easy it is to use a file from the fileupload control.
Dim t_id As Integer = Convert.ToInt32(Request.QueryString("id"))
open()
Dim picture As New SqlParameter("#picture", pictureFileUpload.FileBytes)
Dim id As New SqlParameter("#id", t_id)
myCommand = New SqlCommand("spChangeImage")
myCommand.CommandType = CommandType.StoredProcedure
myCommand.Connection = conn
myCommand.Parameters.Add(picture)
myCommand.Parameters.Add(id)
myCommand.ExecuteNonQuery()
close()
Now I need a way to open an image file and set it as a parameter in a similar manner, but I've no clue as to how to go about doing that. All the search results are focused on opening and viewing an image in html, I just need the binary to use it in the query. I'm trying to use binaryreader but even then I've no idea how to actually map the file to begin with.
Thanks in advance for any help!
Personally, I wouldn't store this image in the database when the user deletes their value. I would set the column to null. When writing the image I would detect if the column is null, then read the file and write it to the response. If you do this, then you won't need to accumulate anything into a local buffer, you can just write each buffer to the response as it is read. You can use FileInfo.Length to determine the content length of the response.
If you insist on putting the image in the DB, you can also use FileInfo.Length to determine the size of buffer you need to hold the image. Use your BinaryReader to read this length of bytes into the buffer. The buffer then becomes your parameter to the SQL command.
this might help.
How can I export the data in my webapp to an Excel sheet from ASP.NET (VB.NET,SQL 2005)?
change the contenttype of your ASP.Net page
Response.ContentType = "application/ms-excel"
One of my most popular blogs is how to generate an Excel document from .NET code, using the Excel XML markup (this is not OpenXML, it's standard Excel XML) - http://www.aaron-powell.com/linq-to-xml-to-excel
I also link off to an easier way to do it with VB 9.
Although this is .NET 3.5 code it could easily be done in .NET 2.0 using XmlDocument and creating the nodes that way.
Then it's just a matter to set the right response headers and streaming back in the response.
SpreadsheetGear for .NET will do it. You can find a bunch of live ASP.NET samples with C# & VB.NET source on this page.
Disclaimer: I own SpreadsheetGear LLC
If you can display your data in a GridView control, it inherently supports "right-click-->Export to Excel" without having to write any code whatsoever.
SQL Server Reporting services would be the best way to export data from an application into Excel.
If you dont have access to / dont wan't to use reporting services depending on the data you want to extract / format possibly using a CSV structure instead of Excel may be easiest.
Use the Microsoft.Office.Interop.Excel dlls to create excel files with your data and then provide links to download the files using Hunter Daley's download method...
As a general solution, you may want to consider writing handler (ashx) for exporting -- and pass either the query parameters to recreate the query to generate the data or an identifier to get the data from the cache (if cached). Depending on whether CSV is sufficient for your Excel export you could just format the data and send it back, setting the ContentType as #Hunter suggests or use the primary interop assemblies (which would require Excel on the server) to construct a real Excel spreadsheet and serialize it to the response stream.
I prefer to use a OLEDB connection string.
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Excel.xls;Extended Properties="Excel 8.0;HDR=Yes;IMEX=1";
Not sure about exporting a page but if you just want to export a dataset or datatable
HttpContext.Current.Response.Clear()
HttpContext.Current.Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", fileName))
HttpContext.Current.Response.ContentType = "application/ms-excel"
Dim sw As StringWriter = New StringWriter
Dim htw As HtmlTextWriter = New HtmlTextWriter(sw)
Dim table As Table = New Table
table.RenderControl(htw)
' render the htmlwriter into the response
HttpContext.Current.Response.Write(sw.ToString)
HttpContext.Current.Response.End()
I use almost the same exact code as CodeKiwi. I would use that if you have a DataTable and want to stream it to the client browser.
If you want a file, you could also do a simple loop through each row/column, create a CSV file and I guess provide a link to the client - you can use a file extension of CSV or XLS. Or if you stream the resulting file to the client it will prompt them if they want to open or save it to disk.
The interops are (well were last time I tried them) great for small datasets, but didn't scale well - horrifically slow for larger datasets.