ASP.NET Export - Response not ending? - asp.net

I'm trying to export some text to a text file, and that part works fine. The trouble is that the text files get a bunch of HTML/.NET output at the bottom of them... In other words, it's like the response isn't ending and the page is trying to write the rest of the page. Here's the code:
Private Sub WriteData(ByRef Context As System.Web.HttpContext, Data As List(of String), fileName as String)
With Context.Response
.Clear()
.ClearHeaders()
.ClearContent()
.AddHeader("content-disposition", String.Format("attachment; filename={0}", fileName))
.ContentType = contentType
End With
For Each curValue in Data
Context.Response.Write(curValue)
Context.Response.Write(Environment.NewLine)
Next
Context.ApplicationInstance.CompleteRequest()
Context.Response.End()
End Sub
To call this, I just pass the HttpContext.Current and a list of data.
Does anybody know why this might happen? I'm not sure how to interpret it, and I've looked all over without much luck. My assumption was that the response wasn't actually ending with "Response.End()"...
Thanks,
Mike

My assumption is that you're using an .aspx to do this.
This would be a perfect scenario for a Generic Handler. Try using .ashx instead.
Here is a pretty simple tutorial if you need more info:
http://www.brainbell.com/tutorials/ASP/Generic_Handlers_%28ASHX_Files%29.html

Related

Different ways of ending a context response

I was working with a generic handler that sends back an XML file as the response, and using code that I already had that did the same thing, from 2 different sources.
The thing is, both sources end their block of code differently, first I have this block
context.Response.Clear()
context.Response.AppendHeader("Content-Disposition", "Attachment; filename=filename")
context.Response.ContentType = "text/xml"
context.Response.Write(myXML)
context.Response.Flush()
context.Response.End()
And then I have the same thing, except that the last line is context.ApplicationInstance.CompleteRequest() instead of context.Response.End()
So I wanted to know what was the difference between both of those lines and which one should I be using
Thanks.

Excel VBA query external .aspx page and retrieve data

I've been struggling with this for about a day. Basically, I want to write an excel macro to loop through a list in excel, query a webpage and retrieve some data. Ideally I just want to retrieve the data I need so I can place it in an adjacent cell, but I'd do whatever it takes at this point.
The page is ASP.net, which I have no experience in; if it was .php I could probably manage, but I’m not even sure how to post to .aspx through javascript.
I can loop through my data just fine, and once I get the data I can write it to excel, so there are two parts I’m struggling with:
Part 1 – querying the webpage
This is the page I want to query. I need to search in Property Address and retrieve data from the results. The address I'll use for the example is 400 W Church St. I thought it may be simple to submit a form like ".../ParcelSearch.aspx?name=...&value=...", but no dice.
Part 2 – grabbing the data
On the results, there is a table DetailsSummary_Master up top, with fieldsets that are defined with <legend> tags. I need the data in <legend>Municipality</legend>:
I can’t figure out what to do, loop through the <td>s? I thought maybe I could GetElementByID or maybe by tag, but I can’t seem to figure it out.
VBA
I used a few SO threads to try to figure it out so far. First, Second and Third, but I can't even seem to get it to POST properly. I'm keeping the subs separate for now.
This is what I have (stolen from the other thread) in regards to my problem:
Sub SubmitForm()
Dim objIE As Object
Dim xmlhttp As Object
Dim ieButton As Object
Dim strResponse As String
Dim strUrl As String
Dim strID As String
Dim strValue As String
Dim strSubmit As String
strID = "?name=ctl00_ctl00_ctl00_ctl00_ContentMain_ContentMain_ContentMain_ContentMain_TabContainer1_Searches_SubTabContainer1_QuickSearches_CompositAddressSearch1_AddressSearch1_ctl00_Address&value="
strValue = "400 W Church St"
strSubmit = strID & strValue
strUrl = "http://www.ocpafl.org/searches/ParcelSearch.aspx"
Set objIE = CreateObject("InternetExplorer.Application")
objIE.navigate "about:blank"
Set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP")
'~~> Indicates that page that will receive the request and the type of request being submitted
xmlhttp.Open "POST", "http://www.ocpafl.org/searches/ParcelSearch.aspx", False
'~~> Indicate that the body of the request contains form data
xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
'~~> Send the data as name/value pairs
xmlhttp.Send "strSubmit"
strResponse = xmlhttp.responseText
objIE.navigate strUrl
objIE.Visible = True
Do While objIE.readystate <> 4
DoEvents
Loop
objIE.document.Write strResponse
Set xmlhttp = Nothing
End Sub
I don't actually need to run it through IE, I'd like to run it all hidden. I'm running this on Excel 2007 at work, but I have 2010 at home. We also have ridiculous IE8, so the less of that, the better. And I can loop or use an array, but I just can't seem to interface with the query. Any help would be greatly appreciated.
For making the query, given the complexity of the form fields that the ASPX page is expecting on postback, you might find it easier to control the browser when making this call. It will be rather slow, but it should work.
A fairly reliable tool for this is Selenium, and there are plugins to control Selenium from Excel VBA.
Edit: This Excel VBA code snippet should read out "Municipality Orlando". You need to parameterize the below code and add cases for error conditions for your final version to query by any street address to get its municipality. This should get you started though. I used Selenium IDE with Firefox to generate the VBA code based on recording user actions, and then came up with an XPath query to grab the text.
Dim selenium As New SeleniumWrapper.WebDriver
selenium.Start "firefox", "http://www.ocpafl.org/searches/ParcelSearch.aspx"
selenium.setImplicitWait 5000
selenium.setImplicitWait 5000
selenium.Open "/searches/ParcelSearch.aspx"
selenium.Click "id=popup_ok"
selenium.Type "id=ctl00_ctl00_ctl00_ctl00_ContentMain_ContentMain_ContentMain_ContentMain_TabContainer1_Searches_SubTabContainer1_QuickSearches_CompositAddressSearch1_AddressSearch1_ctl00_Address", "400 W Church St"
selenium.Click "id=ctl00_ctl00_ctl00_ctl00_ContentMain_ContentMain_ContentMain_ContentMain_TabContainer1_Searches_SubTabContainer1_QuickSearches_PropertyNameSearch1_ctl00"
selenium.Click "id=ctl00_ctl00_ctl00_ctl00_ContentMain_ContentMain_ContentMain_ContentMain_TabContainer1_Searches_SubTabContainer1_QuickSearches_CompositAddressSearch1_AddressSearch1_ctl00_ActionButton1"
Dim municipalityResult As String
municipalityResult = selenium.getText("//fieldset[contains(legend,'Municipality')]")
selenium.stop

VB.Net - Validating XML using DTD

I've got myself a bit of a problem that I can't seem to figure out. I'm trying to programatically validate a generated XML file using a DTD using the following instructions from Microsoft (Validation Using a DTD with XmlReader
Here's my code thus far:
Private Sub BTN_ValidateXMLdoc_Click(sender As Object, e As EventArgs) Handles BTN_ValidateXMLdoc.Click
Dim JobNumber As String = Me.HNF_JobName.Value
Dim XMLPath As String = "N:\" & JobNumber & "\" & JobNumber & ".xml"
' Set the validation settings.
Dim settings As XmlReaderSettings = New XmlReaderSettings()
settings.DtdProcessing = DtdProcessing.Parse
settings.ValidationType = ValidationType.DTD
settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings
settings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema
AddHandler settings.ValidationEventHandler, AddressOf ValidationCallBack
' Create the XmlReader object.
Dim reader As XmlReader = XmlReader.Create(XMLPath, settings)
' Parse the file.
While reader.Read()
End While
End Sub
' Display any validation errors.
Private Shared Sub ValidationCallBack(sender As Object, e As ValidationEventArgs)
MsgBox(String.Format("Validation Error: {0}", e.Message), MsgBoxStyle.OkOnly)
End Sub
Now.... Here in lies my problem. For some reason, the ValidationCallBack EventHandler never gets fired. If an error occurs during the reader.Read() executing it throws an exception error.
Correct me if I'm wrong, but shouldn't the ValidationCallBack sub be called?
There are errors in the XML file but instead of it being handled by the event handler it's just throwing an exception....
I'm open to any ideas as to what may be going on here?
Your code implies the DTD is embedded in the XML document itself. While that's possible, it's unlikely to be what you want. I suspect your test is failing because there is no embedded DTD in the actual XML document.
If the DTD is indeed external to the XML document, you need to tell your XmlReaderSettings where to find it.
Remove the line
settings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema from your code.
Make sure there's a DOCTYPE in your XML document to specify the DTD. If there isn't, you may need to insert it before validation.
If you want to escape the overhead of downloading the DTD each time, you should create an XmlResolver. See Problem validation a XML file with a local DTD file in C# for an example.
Consider converting your DTD to an XML Schema. Schemas are more natural in XmlReader. DTDs don't understand XML namespaces.

Output XML as file in ASP.NET

I'm having difficulty sending an XML stream to the client browser. I've researched this considerably and everything looks right - moreover, similar code works in a previous version of this app. Any ideas what I could be doing wrong?
The following code throws no errors, but does not download a file on the client machine.
Public Shared Sub Export(ByVal source As DataTable)
Try
With Current.Response
Dim xml As String = CreateExcelXMLFromDataTable(source.DefaultView)
.Clear()
.Buffer = True
.ContentType = "application/vnd.ms-excel"
.AddHeader("Content-Disposition", String.Concat("attachment;filename=", "export.xlsx", ";"))
.AddHeader("Content-Length", xml.Length.ToString)
.Charset = ""
.Write(xml)
.Flush()
.Close()
End With
Catch ex As Exception
Console.WriteLine(ex.Message.ToString)
End Try
End Sub
Thanks!
If you are calling this function in an Ajax request it will not work. You have to cause a full postback to send the file to the client.
You can send the file without causing a full postback in the current page using an popup window (window.open) or an iframe with the URL of the download asp.net page, which will call the Export function.

Creating a dynamic graphic in asp.net

I am busy creating a control in asp.net. The control consists of some text and an image. The image will be used to display a graph. The control gets the data for the graph by reading it from a database. It seems I have two options to display the graph in the image box. First, I can create a jpg from the data and save the file on the server. I can then load this file into the image box. I think this would cause a problem if various users try to access the site at the same time, so I don't think it is a good option. The other options is to create a file called output, that outputs the graph like this: objBitmap.Save(Response.OutputStream, ImageFormat.Gif)
I can then display the image like this in my control: Image1.ImageUrl = "output.aspx"
The problem that I am facing is how do I get the data from my control to the output page? As far as I know it is too much data to pass as a parameter. If there is another better method of doing it, please let me know
Thanks
You can write the image content to the response of output.aspx. Something like this (taken from one of my existing GetImage pages:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strFilename As String
strFilename = Request.QueryString("filename")
Dim strPath As String = AppSettings("ProxyImageSavePath") & strFilename
Response.Clear()
Response.ContentType = "image/jpeg"
If Not IO.File.Exists(strPath) Then
'erm
Response.Write("file not found")
Else
Response.WriteFile(strPath)
End If
Response.End()
End Sub
Edit: I've just realised this may not be the solution you're looking for; Your webserver should be able to cache this though.
You need handlers. See in this article, Protecting Your Images, section "Creating the ImageHandler HTTP Handler", you'll find the code how to write the handler, so it outputs an image. You don't need all, it's only an example.
You also need to register the handler in the web.config.
To reference it Image1.ImageUrl = "handler.ashx?graphdata=xxxx". Use QueryString to get the data source to generate the graph.

Resources