Classic ASP test if Server can create object - asp-classic

With this code:
Dim xmlDOM
Set xmlDOM = Server.CreateObject("MSXML2.DOMDocument.3.0")
How can I test that the CreateObject function has been successful?

If it didn't work you might get an error. Otherwise, you could use the following code:
Dim xmlDOM
'dont fail on error'
On Error Resume Next
Set xmlDOM = Server.CreateObject("MSXML2.DOMDocument.3.0")
On Error GoTo 0 'turn error handling off again'
If Not xmlDOM Is Nothing Then
'not null: it worked'
Else
'xmlDOM is nothing. It was not able to create the object. '
'Check create permissions in COM+'
End If

Related

Get result from chilkatHttp.PostUrlEncodedAsync in VB6

I am using chilkat Http.PostUrlEncodedAsync to send some data to a server and get a JSON response. When the Http_TaskCompleted Event is fired, the task.ResultType returns "object" but there is no task.GetResultObject.
The reply is received correctly (it is present in httpSessionLog.txt) but how do I get it ?
After a different search I have found it:
Private Sub Http_TaskCompleted(ByVal task As Chilkat_v9_5_0.IChilkatTask)
Dim response As New ChilkatHttpResponse
Dim success As Long
success = response.LoadTaskResult(task)
If (success <> 1) Then
Debug.Print response.LastErrorText
Exit Sub
End If
Debug.Print response.BodyStr 'this is the response string
End Sub

Testing if object Is Nothing results in 'Object required' error

I am supporting some classic ASP pages, one of which uses and re-uses an object conn and disposes of it either when the .asp page finishes processing or right before the page redirects to another page.
<%
dim conn
...
set conn = server.CreateObject("adodb.connection")
...
sub cleanUp()
conn.Close
set conn = nothing
end sub
...
sub pageRedirect(url)
call cleanUp()
response.Redirect url : response.End
end sub
...
' very end of file
call cleanUp()%>
I've found that if there is a redirect, I get a server error right at the line conn.Close, Microsoft VBScript runtime error '800a01a8' Object required. I figure there's no reason why that line would execute more than once but to be safe I rewrote the function
sub cleanUp()
if(not (conn Is Nothing)) then
conn.Close
set conn = Nothing
end if
end sub
But I still get that exact error, now at the line if(not (conn Is Nothing))!! I thought the purpose of Is Nothing was to do a test before using the variable name conn precisely to prevent that 'object required' error, but the test is throwing the same error.
What other test can I use to make sure conn isn't referenced if it'd already been set to Nothing?
is nothing is used to test for an object reference, if the variable does not contain such then the test is invalid & raises an error, so conn can only be tested after its been set to something.
You can;
if isobject(conn) then
if not (conn Is Nothing) then set conn = nothing
end if
Use option explicit (each time a script runs without option explicit, a puppie dies out there), you probably would have detected the problem earlier as Nilpo mentioned.
When you dim a variable that you are going to use as an object reference and test it on Nothing, make it a habbit to set it to Nothing at initialization time(*): dim myObject : Set myObject = Nothing.
(*) Not really at initialization, because the dim's are handled before a routine starts, but when you put all your dim's at the top of a routine, it will practically be the same.
Use the IsNothing function. You should also check that it is an object.
sub cleanUp()
if Not IsNothing(conn) then
if IsObject(conn) then
conn.Close
end if
set conn = nothing
end if
end sub
That being said, I would do it like this since setting a variable to nothing does no harm.
sub cleanUp()
if IsObject(conn) then
conn.Close
end if
set conn = nothing
end sub
More importantly though, your problem is that conn is not in scope for your subroutine. You should probably pass it in as a parameter.

Classic asp - response.redirect in a sub - error handling

I wish to do the following ... Provide a page a developer can redirect to provided an error occurs ... like a vb error connection couldn't open or object couldn't be found ... or a database error is raised ... but since I moved the redirect into a sub the page doesn't actually redirect ... Is it possible that I simply can't redirect from a sub? Seems weird.
Run a stored procedure that raises an error
Dim cmd
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = con
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "spReturnDBException"
cmd.Execute
Call a handle errors function that sets up some session parms and redirects if neccessary
HandleErrors con _
, Request.ServerVariables("PATH_INFO") _
, "An error occurred while trying to save sessions." _
, "Actual Error: " + Err.Description + " EmpNo: " + Session("EmpNo") _
+ ". QueryString: " + Request.Querystring _
, 0
This would be the sub called.
sub HandleErrors( connection, WebPagePath, GenericErrorMessage, DebugInfo, Severity)
//Check for vb errors
if Err.Number <> 0 Then
Session("WebPagePath") = WebPagePath
Session("SafeErrorMessage") = GenericErrorMessage 'Session("SafeErrorMessage") + "A connection was dropped while trying to complete sessions."
Session("DebugInfo") = DebugInfo ' Err.Description
Session("LineNo") = Err.Line
Session("StackTrace") = ""
Session("Severity") = Severity
response.redirect("Error.asp")
//error occurs
elseif connection.Errors.count <> 0 then
response.write("a database error occurred.")
// Store safe error message / # in session
Session("WebPagePath") = WebPagePath
Session("SafeErrorMessage") = GenericErrorMessage 'Session("SafeErrorMessage") + "An error has occurred while trying to save sessions."
Session("DebugInfo") = DebugInfo '"Some extra added debug info from the webpage"
Session("LineNo") = 0
Session("StackTrace") = ""
Session("Severity") = Severity
Dim objError
for each objError in connection.Errors
// Store safe error number in session
Session("SafeErrorNumbers") = Session("SafeErrorNumbers") + objError.Description
if connection.Errors.Count > 1 then
Session("SafeErrorNumbers") = Session("SafeErrorNumbers") + "|"
end if
next
response.Redirect("Error.asp")
end if
Err.Clear
end sub
To display the Error line number:
set objError = Server.GetLastError()
strErrorLine = objError.Line
Here are a couple threads on using Err.line:
http://www.daniweb.com/web-development/asp/threads/11615
http://www.sitepoint.com/forums/showthread.php?279612-ASP-Error-Handling.-Err.Line-weird-behavior
I can't explain why you are getting the results you are. I can tell you that if your code reachs a line that contains Response.Redirect that redirect will happen regardless of whether its a in a Sub procdure or not.
I would make this suggestion. Stop using using On Error Resume Next. It is very painful way to deal with exceptions.
Instead change HandleErrors into GenerateConnectionError. Its job would be to compose error source and description strings and deliberately call Err.Raise with a user define error number (I tend to use 1001).
Now your Error.asp should be installed in the root of your application as the handler for the 500.100 http status code. When a script error occurs IIS will look to the current error pages collection for the location to determine what to do. You will have set this to execute a URL and specified your Error.asp as the URL.
When Error.asp is executed it will find details about the page being requested from QueryString. Here you can also use Server.GetLastError to get an ASPError object from which you can get other details about the error.
Using this approach will detail with any script error without requiring the developer to remember to pepper their code with HandleError code. The developer need on remember to call GenerateConnectionError when performing code that is using an ADODB.Connection and even then you could probably abstract that inside an .asp include file.

checking if row was inserted

I am trying to check whether a row is getting inserted into my database. It is throwing an error even when it does insert (it's a database issue that will get resolved later when I get a newer version of Microsoft Access), so I can't check whether the insert is successful based on whether there's an error or not. I think I need to check the AffectedRows of something, but I'm not sure what. I've been looking for info on how to do this but I can't figure out how to make it work for my exact situation. Here's a general idea of what my code looks like:
Protected Sub Wizard1_FinishButtonClick(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.WizardNavigationEventArgs) Handles Wizard1.FinishButtonClick
'code for collecting data...
'Define Connection
Dim myConn As New OleDbConnection
myConn.ConnectionString = AccessDataSource1.ConnectionString
myConn.Open()
'Insert command
Dim myIns1 As New OleDbCommand("INSERT INTO tableCourse 'long insert command here...
'Execute command and handle errors
Try
myIns1.ExecuteNonQuery()
Catch myException5 As Exception
End Try
'Close connection
myConn.Close()
-UPDATE-
I tried it like this:
'Execute command, handle errors, and check if row was inserted
Dim numInserted As Integer = 0
Try
numInserted = myIns1.ExecuteNonQuery()
Catch myException As Exception
Finally
If numInserted = 0 Then
Label1.Text = "Sorry, an error occured."
Else
Label1.Text = "Thank you! Your new course approval request has been submitted."
End If
End Try
But the numInserted is coming out as 0 every time even though the insert is successful. It may have to do with the fact that myIns1.ExecuteNonQuery() throws an error even though the insert is successful.
-EDIT- I discovered that the "duplicate values" error is because it is somehow attempting to insert the record twice. I have no idea why it's doing that though.
The ExecuteNonQuery function returns the affected number of rows...
Dim numInserted as Integer = myIns1.ExecuteNonQuery()
If numInserted = 0 Then
' no rows were inserted...throw exception?
End If
The symptoms you are describing (known no duplicates, but inserts throw duplicate errors) sound like your Access database needs Compacting and Repairing.
You should do this on a regular basis. (Always backup up first).

I cannot seem to load an XML document using ASP (Classic), IIS6. Details inside

So I am writing a web application for use within my organization. The application requires that it know who the current user is. This is done by calling the Request.ServerVariables("AUTH_USER") function, which works great as long as 'Anonymous Access' is disabled (unchecked) and 'Integrated Windows Authentication' is enabled (checked) within IIS for this subweb.
Unfortunately by doing this I get an 'Access Denied' error when I hit the load method of the XML DOM.
Example code:
dim urlToXmlFile
urlToXmlFile = "http://currentwebserver/currentsubweb/nameofxml.xml"
dim xmlDom
set xmlDom = Server.CreateObject("MSXML2.DOMDocument")
xmlDom.async = false
xmlDom.load( urlToXmlFile ) ' <-- this is where I get the error!
I've looked everywhere and cannot find a solution. I should be able to load an XML file into the DOM regardless of the authentication method.
Any help would be appreciated. So far the only two solutions I can come up with are:
a) create a new subweb that JUST gets the current user name and somehow passes it back to my XML reading subweb.
b) open up security on the entire system to 'Everyone', which works but our IS department wouldn't care for that.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Here was my original code, which cause the access denied error:
dim urlToXml
urlToXml = "http://someserver/somesomeweb/nameofxml.xml"
dim xmlDom
set xmlDom = Server.CreateObject("MSXML2.DOMDocument")
xmlDom.loadXML( urlToXml )
dim xsl
set xsl = Server.CreateObject("MSXML2.DOMDocument")
xsl.async = false
xsl.load(server.MapPath("somexsl.xsl"))
Response.Write( xmlDom.transformNode(xsl) )
xmlDom.save( server.MapPath("accounting/somexml.xml") )
Now, here is my new code thanks to thomask:
dim urlToXml
urlToXml = "http://someserver/somesomeweb/nameofxml.xml"
set http = CreateObject("MSXML2.ServerXMLHTTP.3.0")
http.Open "GET", urlToXml, false
http.Send()
dim xmlDom
set xmlDom = Server.CreateObject("MSXML2.DOMDocument")
xmlDom.loadXML( http.responseXML.xml )
dim xsl
set xsl = Server.CreateObject("MSXML2.DOMDocument")
xsl.async = false
xsl.load(server.MapPath("somexsl.xsl"))
Response.Write( xmlDom.transformNode(xsl) )
xmlDom.save( server.MapPath("newxml.xml") )
Again thank you very much thomask.
You might wanna look at MSXML2.ServerXMLHTTP(.3.0 - 6.0) to specify the user credentials. If the Content-Type is configured correctly, ServerXMLHTTP should give you the DOMDocument in the responseXml property.
Dim http
Set http = CreateObject("MSXML2.ServerXMLHTTP.3.0")
http.Open("GET", "http://currentwebserver/currentsubweb/nameofxml.xml", false, "user", "pass")
http.Send()

Resources