Error trying to download an XML file - asp.net

I'm trying to download an XML file, the file already exists in the specified path, I am not familiar with VB and probably this code is not right, I need help just in it to be able to download an existing xml file, here's the code:
Protected Sub DownloadFile(ByVal sPath As String)
Dim TargetFile As New System.IO.FileInfo(sPath)
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=" +
TargetFile.Name)
Response.AddHeader("Content-Length", TargetFile.Length.ToString())
Response.ContentType = "text/xml"
Response.WriteFile(TargetFile.FullName)
Response.End()
End Sub
The error returned in the console:
Uncaught Error: Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled.
Contextualizing the problem:
I have serialized an object and created an XML file, then I would simply like to download this file, my difficulty is to download the file.
Dim oObj1 As New System.Xml.Serialization.XmlSerializer(GetType(eSocial.Eventos.evtTabHorTur.eSocial))
Dim sFileName = Date.Now.ToString("yyyyMMddHHmmss") & ".xml"
Dim sPath = Constantes.Ambiente.CaminhoSite & "temp\" & sFileName
Dim oFile As New System.IO.StreamWriter(sPath)
oObj1.Serialize(oFile, eSocialCamposXml)
oFile.Close()

You are saying you are having difficulty downloading but there is nothing in the code except showing writing a file and then serializing a file. You would be using a 'StreamReader' or similar manner to READ a file. Here is a simple example. Say I have an xml structure on a file location with the schema like:
<root>
<test>Data</test>
</root>
I could write this in VB.NET to get it:
Sub Main()
Dim xmlFile As XDocument
Dim fileLocation = "D:\\Test Code\\Test.xml"
Using sr = New StreamReader(fileLocation)
xmlFile = XDocument.Parse(sr.ReadToEnd())
End Using
Console.WriteLine(xmlFile.Root.Element("test").Value.ToString)
Console.ReadLine()
End Sub

Related

How to download file without full file path using Response TransmitFile in ASP.NET

I am downloading the file using the below code. But, downloading the file is showing the full path of the filename.
Example :
Filaname : Test.asd
File path : \tdsment.tds.intranet\USA\PART1\2022
current download file (after downloading) : _tdsment.tds.intranet_USA_PART1_2022_Test.asd
I don't want to show the full file path after downloading the file.
Simply my downloaded file should be "Test.asd"
It means Expecting download file name : Test.asd
Public Sub TreeView1_SelectedNodeChanged(sender As Object, e As EventArgs)
Dim ChildNode1 As String = TreeView1.SelectedValue
filename = GetFileName(ChildNode1)
Response.Clear()
Using oBinaryReader As BinaryReader = New BinaryReader(File.OpenRead(filename))
Response.ContentType = "application/octet-stream"
Response.AppendHeader("Content-Disposition", "attachment; filename=" + filename)
Response.TransmitFile(filename)
Response.Flush()
End Using
End Sub
Private Function GetFileName(ChildNode1 As String) As String
filepath = "\\tdsment.tds.intranet\USA\PART1\2022\"
Dim Result As String
Result = String.Concat(filepath, ChildNode1)
Return Result
End Function

How to send multiple files with Response. ASP.NET

I'm trying to call below code in a loop hundreds of times:
Sub ExportReport(ByVal en As MyReport)
Dim warnings As Warning() = Nothing
Dim streamids As String() = Nothing
Dim mimeType As String = Nothing
Dim encoding As String = Nothing
Dim extension As String = Nothing
Dim bytes As Byte()
bytes = aReport.ServerReport.Render("WORD", Nothing, mimeType, encoding, extension, streamids, warnings)
Response.Buffer = True
Response.Clear()
Response.ContentType = mimeType
Response.AddHeader("content-disposition", "attachment; filename=" & en.ToString() & "." + extension)
Response.BinaryWrite(bytes)
Response.Flush()
Response.End()
End Sub
And I'm getting this error :
Server cannot append header after HTTP headers have been sent.
How can I change the code so that I can loop this piece of code? Thanks.
EDIT :
I added this line after Response.End()
Response.Redirect(Request.Url.AbsoluteUri)
And I get this error :
Cannot redirect after HTTP headers have been sent.
WWW works on a request / response mechanism. For every request there is only 1 response. You cannot change that basic mechanism. When browser sends a request it is expecting one and only one response. So if it receives more than 1 response, it either issues a warning to the user to block this behaviour or may choose to ignore the extra responses by itself. Thus these extra responses may be lost.
Having said that you have 2 options with you:
Zip all the files that you want to download and download as a single file.
You can use Popular framework Ionic.Zip.
First, keep all your files in a local directory on the server.
Then use this library to zip the entire folder.
Pseudo code:
Imports (var zip = New Ionic.Zip.ZipFile())
{
zip.AddDirectory("DirectoryOnDisk", "rootInZipFile")
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=DownloadedFile.zip")
Response.ContentType = "application/zip"
zip.Save(Response.OutputStream)
Response.End()
}
Add a mechanism to issue multiple request using Javascript to get multiple responses, so browser still treats this behaviour as normal.
A normal web page will have a load of (headers) stuff set up for you already, but you don't want any of that: you want complete control over what is sent to the browser. If you cause a redirect to something which sends the headers shown in code later here, the browser will (normally) download the data.
In the code-behind you can have something like
Protected Sub btn_click(ByVal sender As Object, ByVal e As EventArgs) Handles btn.Click
Response.Redirect("~/sendfile.ashx?ref=" & enReference, False)
Context.ApplicationInstance.CompleteRequest()
End Sub
You will also need to add a generic handler (right-click on the project in Solution Explorer, Add->New Item... -> Visual Basic--Web--General choose "Generic Handler"; give it a name like sendfile.ashx) which is somewhat like
Imports System.IO
Public Class sendfile
Implements System.Web.IHttpHandler, IReadOnlySessionState
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim enReference = context.Request.QueryString("ref")
' do whatever is needed to get the report from enReference '
Dim bytes As Byte() = aReport.ServerReport.Render("WORD", Nothing, mimeType, encoding, extension, streamids, warnings)
Dim downloadName = yourfilename & "." & yourextension
context.Response.ContentType = "application/octet-stream"
context.Response.AddHeader("content-disposition", "attachment; filename=""" & downloadName & """" )
context.Response.BinaryWrite(bytes)
End Sub
ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
and you will need to work out the code to create the data to be sent.
If you don't need to use session state then you can remove the , IReadOnlySessionState part on the Implements line.
You might need to add context.Response.Flush(). If you find that the response does not have a Content-Length header, then you ought to add one so that the browser can show a meaningful download progress.

Convert excel file to byte array

I'm using ASP.net with VB codebehind.
I need to be able to convert an excel file created in code into a byte array in order to send it to the client. Without saving the file to the server.
this is how i created the excel document
Dim APP As Excel.Application = New Excel.Application
Dim missing As Object = System.Reflection.Missing.Value
Dim Workbook As Excel.Workbook = (APP.Workbooks.Add(missing))
Dim worksheet As Excel.Worksheet = Workbook.ActiveSheet
'..Fill cells in worksheet..
This is how i transmit it:
Response.Clear()
Response.ClearContent()
Response.ClearHeaders()
Response.Cookies.Clear()
Response.Cache.SetCacheability(HttpCacheability.Private)
Response.CacheControl = "private"
Response.Charset = System.Text.UTF8Encoding.UTF8.WebName
Response.ContentEncoding = System.Text.UTF8Encoding.UTF8
Response.AppendHeader("Content-Length", filebytes.Length.ToString())
Response.AppendHeader("Pragma", "cache")
Response.AppendHeader("Expires", 60)
Response.AppendHeader("Conetnt-Disposition", "attachement; filename='MostIssuesByModelReport.xlsx'; size=" & filebytes.Length.ToString() & "; creation-date=" & Date.Now.ToString("R") & "; modification-date=" & Date.Now.ToString("R") & "; read-date=" & Date.Now.ToString("R"))
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
'write to client
Response.BinaryWrite(filebytes)
Response.End()
I just need to get the content of Workbook into filebytes
EDIT:
After looking around a bit more I can now make it download a file, however this file does not use the filename specified in the above code, it uses the name of the asp server page that the user is on, it also has a .aspx extension..however if I force it to open in excel it is correct. Besides popping up saying the source may be corrupted. Why is this happening and how can I fix it?

PDFHandler.ash error when there is no file

I am having an issue with my ASHX handler that is generating PDF.
When the user hits a "View PDF" button, it will look in the database for the PDF file and display it, but if there isn't a PDF file there it should display a blank page saying "no PDF available", but instead I get a "null reference" error on this line of code:
ms.WriteTo(context.Response.OutputStream)
Below is the code for the handler:
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
'This class takes the uniqueidentifier of an image stored in the SQL DB and sends it to the output stream
'This saves storing copies of image files on the web server as well as in the DB
context.Response.Clear()
If context.Request.QueryString("fileSurveyID") IsNot Nothing Then
Dim filesID As String = context.Request.QueryString("fileSurveyID")
Dim fileName = String.Empty
Dim ms As MemoryStream = GetPDFFile(filesID)
context.Response.ContentType = "application/pdf"
context.Response.AddHeader("Content-Disposition", "attachment;filename=" & fileName)
context.Response.Buffer = True
ms.WriteTo(context.Response.OutputStream)
context.Response.End()
Else
context.Response.Write("<p>No pdf file</p>")
End If
End Sub
Can anyone tell me how to get rid of this error?
Simple If..Then should do the trick:
Dim ms As MemoryStream = GetPDFFile(filesID)
If ms IsNot Nothing Then
context.Response.ContentType = "application/pdf"
context.Response.AddHeader("Content-Disposition", "attachment;filename=" & fileName)
context.Response.Buffer = True
ms.WriteTo(context.Response.OutputStream)
context.Response.End()
End If
You probably want to move the following out of the if:
context.Response.End()
so it execute each time regardless.
However you say the following line executes when no PDF available:
ms.WriteTo(context.Response.OutputStream)
which would suggest something wrong with your if condition

Importing data from Excel - VB.NET

I am trying to import some data from an excel spreadsheet, using VB.net
my steps are:
first the user uploads the file to the server
then i want to read the file from the server to then populate a gridview
this is what i have:
Protected Sub btnUpload_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnUpload.Click
Dim filepath As String = ""
If FileUpload1.HasFile Then
Try
If (FileUpload1.PostedFile.ContentType = "application/vnd.ms-excel") Then
Dim filename As String = Path.GetFileName(FileUpload1.FileName)
'Session("userid") & "-" & Date.Now()
filepath = "\excel\" & Session("userid") & "_" & Now.Date().ToString("Mdy") & "_" & filename
FileUpload1.SaveAs(Server.MapPath("~/") & filepath)
ReadExcel(filepath)
Else
StatusLabel.Text = "Only Excel file types are accepted"
End If
Catch ex As Exception
StatusLabel.Text = "Upload status: The file could not be uploaded. The following error occured: " + ex.Message
End Try
End If
End Sub
Sub ReadExcel(ByVal filepath As String)
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim DtSet As System.Data.DataSet
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & filepath & "';Extended Properties=Excel 8.0;")
MyCommand = New System.Data.OleDb.OleDbDataAdapter("select * from [NSTS]", MyConnection)
MyCommand.TableMappings.Add("Table", "Net-informations.com")
DtSet = New System.Data.DataSet
MyCommand.Fill(DtSet)
gwResults.DataSource = DtSet.Tables(0)
MyConnection.Close()
End Sub
the error happens with "MyConnection", it tried to look on the "C:/" instead of on the server:
'c:\excel\3_41911_Sample.xls' is not a valid path. Make sure that the path name is spelled correctly and that you are connected to the server on which the file resides.
how can i set the OleDb connection to get the source file from the server instead?
thank you!
nevermind, i got it
i added: Server.MapPath("~/") & filepath and now it works. however, now i'm getting the error:
The Microsoft Jet database engine could not find the object 'NSTS'. Make sure the object exists and that you spell its name and the path name correctly.
NSTS is the name of my first spreadsheet. what am i doing wrong? :(
i was missing a studip dollar sign :) ahh, it all works now!
"select * from [NSTS$]"
thanks!
Use a $ in your sheet's name in the query:
"select * from [NSTS$]"
Your c:\excel\ path is not local path but it is path local to where you are running your application.
If you are running this application from local machine, In order to map c:\excel\ path, you should either map server drive to your windows and use that drive name OR use \\excel as path value.
First - do you know exactly where on the server path the file is being saved to? I'd begin by hardcoding the path to make sure that there isn't anything else squirrely going on.
Looking at your code you're saving the file here...
FileUpload1.SaveAs(Server.MapPath("~/") & filepath)
So... first, are you sure it's saving there? If so then look as where you're reading the file with this call...
ReadExcel(filepath)
Have you tried -
ReadExcel(Server.MapPath("~/") & filepath)?

Resources