I posted last month and before about the lack of examples of using Classic
ASP and RS2005. I simply wanted to create and then export a report as a PDF.
After much research and testing, I came up with ASP code that communicates
with RS using SOAP calls and successfully loads, renders, and exports RS
reports. So, Classic ASP *does* support SOAP (as does any language) - you
just have to handroll the entire thing and understand XML and the
undocumented quirks and flow in RS. Also, in order for this all to work, it
takes custom and non-standard configuration of RS, IIS, SQL Server, etc. to
make it all happen (I had to write it all down because I couldn't
consistently remember all the steps).
Here's my test, non-production, code that will help you understand the steps
of sending SOAP messages and interacting with RS with ASP 3.0. There may be
more elegant ways to do this, but it works.
The hardest part is setting up permissions, users, and such in RS, SQL, and
IIS which was a lot of trial and error and experiments dealing with
"permission denied" stuff.
<%
Dim strFormat, strCustID, strReport
'test parameters
strFormat = "PDF"
strCustID= "5810"
strReport = "record"
Dim errorMsg
errorMsg = "Node Select Error"
Dim strPrefix
Dim strReportPath 'as String
Select Case strReport
Case "record"
strReportPath = "/TestFolder/TestReport"
strPrefix = "test-"
Case "summary"
strReportPath = "/TestFolder/TestReport2"
strPrefix = "test2-"
End Select
Dim strContentType 'as String
Dim strSuffix
Select Case strFormat
Case "HTML4.0"
strContentType = "text/html"
strSuffix = ".htm"
Case "PDF"
strContentType = "application/pdf"
strSuffix = ".pdf"
Case "IMAGE"
strContentType = "image/tiff"
strSuffix = ".tif"
End Select
'the web service
Dim postURL 'as String
postURL = "http://mymachine/ReportServer/ReportExecution2005.asmx"
'the Namespace for Reporting Services
Dim rsns 'as String
rsns =
"http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices"
'====================================================================================
Function ByteArray2Text(varByteArray)
Dim strBuffer, lngCounter
strData = ""
strBuffer = ""
For lngCounter = 0 to UBound(varByteArray)
strBuffer = strBuffer & Chr(255 And
Ascb(Midb(varByteArray,lngCounter + 1, 1)))
'Keep strBuffer at 1k bytes maximum
If lngCounter Mod 1000 = 0 Then
strData = strData & strBuffer
strBuffer = ""
End If
Next
ByteArray2Text = strData & strBuffer
End Function
Sub writeError(responseBody)
Dim errorStr
errorStr = getNodeText(responseBody, "//ErrorCode") & ": " &
getNodeText(responseBody, "//Message") & _
"<br /><br />" & ByteArray2Text(responseBody)
Err.Raise 1, "Reporting Services-SOAP", errorStr
End Sub
Sub writeByteArray(responseBody)
Response.Clear
Response.ContentType = strContentType
if strContentType <> "text/html" then
Response.AddHeader "Content-Disposition", "attachment;
filename=" & strPrefix & strPtID & strSuffix
end if
Response.BinaryWrite getResultAsByteArray(responseBody)
End Sub
Function createExecutionHeader(theExecutionID)
If len(theExecutionID) > 0 then
createExecutionHeader = _
"<soap:Header>" & _
"<ExecutionHeader xmlns=""" & rsns & """>" & _
"<ExecutionID>" & theExecutionID & "</ExecutionID>"
& _
"</ExecutionHeader>" & _
"</soap:Header>"
Else
createExecutionHeader = ""
End If
End Function
Function makeSOAPPackage(theBody, theExecutionID)
makeSOAPPackage = _
"<?xml version=""1.0"" encoding=""utf-8""?>" & _
"<soap:Envelope
xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""" & _
" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""" &
_
" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">" & _
createExecutionHeader(theExecutionID) & _
"<soap:Body>" & theBody & "</soap:Body>" & _
"</soap:Envelope>"
End Function
Function getNodeObject(theResponse, xpathToNode)
set xmldoc = Server.CreateObject("MSXML.DOMDocument")
xmldoc.load(theResponse)
set getNodeObject =
xmldoc.documentElement.selectSingleNode(xpathToNode)
set xmldoc = nothing
End Function
Function getNodeText(theResponse, xpath)
set node = getNodeObject(theResponse, xpath)
if NOT (node is nothing) then
getNodeText = node.text
set node = nothing
else
getNodeText = errorMsg
end if
End Function
Function getResultAsByteArray(theResponse)
set node = getNodeObject(theResponse, "//Result")
node.dataType = "bin.base64"
getResultAsByteArray = node.nodeTypedValue
set node = nothing
End Function
Function sendSOAPRequest(theBody, theMethod, theExecutionID, hasError)
Dim xmlobject
set xmlobject = Server.CreateObject("MSXML2.ServerXMLHTTP")
With xmlobject
.Open "POST", postURL, False
.setRequestHeader "SOAPAction", rsns & "/" & theMethod
.setRequestHeader "Content-Type", "text/xml; charset=utf-8"
.Send makeSOAPPackage(theBody, theExecutionID)
End With
hasError = getNodeText(xmlobject.responseBody, "//" & theMethod &
"Response")
sendSOAPRequest = xmlobject.responseBody
set xmlobject = nothing
End Function
'====================================================================================
Dim strExecutionID, strErrorMessage
strExecutionID = "" 'no execution ID for the first method
Dim responseBody 'as String
strRequest = "<LoadReport xmlns=""" & rsns & """>" & _
"<Report>" & strReportPath & "</Report>" & _
"</LoadReport>"
responseBody = sendSOAPRequest(strRequest, "LoadReport", strExecutionID,
strErrorMessage)
if strErrorMessage <> errorMsg then
strExecutionID = getNodeText(responseBody,
"//executionInfo/ExecutionID")
strRequest = "<SetExecutionParameters xmlns=""" & rsns & """>" & _
"<Parameters>" & _
"<ParameterValue>" & _
"<Name>ptid</Name>" & _
"<Value>" & strCustID & "</Value>" & _
"</ParameterValue>" & _
"</Parameters>" & _
"<ParameterLanguage>en-us</ParameterLanguage>" & _
"</SetExecutionParameters>"
responseBody = sendSOAPRequest(strRequest, "SetExecutionParameters",
strExecutionID, strErrorMessage)
if strErrorMessage <> errorMsg then
strRequest = _
"<Render xmlns=""" & rsns & """>" & _
"<Format>" & strFormat & "</Format>" & _
"</Render>"
responseBody = sendSOAPRequest(strRequest, "Render",
strExecutionID, strErrorMessage)
if strErrorMessage <> errorMsg then
writeByteArray responseBody
else
writeError responseBody
end if
else
writeError responseBody
end if
else
writeError responseBody
end if
%>
Post by l***@gmail.comI have been working on this for over a month and have seen many
requests for help on this. Classic asp does not support SOAP. The soap
toolkit 3.0 keep passing invalid parameters to RS2k5. The best way I
have found to access some aspects of reporting service without
exposing reporting services to the outside world is to make a classic
asp page that proxies url access
I had to ditch soap and do something else.
Here is my setup
Win 2k3, IIS has multiple websites setup, the default website is set
to listen on 127.0.0.1 and has reporting service setup on it,
reporting service is set to anonymous access and the guest account has
full control.
All I need reporting services for is to format reports for excel or
reports that are going to paper.
Report_pdf.asp
Response.Clear
Response.ContentType = "application/pdf"
set xmlhttp = server.CreateObject("Microsoft.XMLHTTP")
xmlhttp.open "GET", "http://localhost/reportserver?%2fReport
%2fSummaryReport&rs:Command=Render&rs:Format=PDF&rc:Toolbar=false",
false
if xmlhttp.Status = 200 then
Response.BinaryWrite xmlhttp.responseBody
Else
Response.Write("Didn't Work")
End if