I am in the middle of creating something similar to what you have described. I am working on integrating a .Net application to a SAS web application (using SAS's Broker architecture). While I am not accessing the data to perform any report output formatting, I am accessing the SAS data across the web from a web server via XML and pulling out the data points that I need to display within datagrids, fields, etc. on web pages rendered in ASP.Net.
The user is presented with a SAS-generated HTML page in which is embedded information required on the ASP.NET side for eventual retrieval of the XML data-island from SAS. Sorry for the verbose message, however, I cannot provide you links to the code anywhere because of my contractural obligations.
I am using the following steps:
- Capture the raw XML that is to be utilized within the report. I used the HTTPWeb.Request which gives you a nice way to access it's FormVars collection for passing any required values to the SAS Broker. Set its URL property to point to the SAS page that is to return XML, and Execute it to
- Create instance of System.Xml.XmlDocument
- Load contents of raw XML into XmlDocument using LoadXml(). Remember that well-formed XML must adhere to the
- Access the Nodes. There are good ways to bind ASP.Net Web controls to XML data islands. Another topic, another day.
I have included some code that is working for me for this purpose:
Code:
Imports System.Net
.
.
.
Public Sub WriteXMLData(URL as String, UserId as String, Password as String)
Dim oXML As New System.Xml.XmlDocument
Dim oRequest As New HTTPWeb.Request
Dim oNode As System.Xml.XmlNode
Dim oRootNode As System.Xml.XmlNode
Dim sRawXML As String
Try
sRawXML = ReadURL(sURL, sSiteLogin, sSitePwd, "")
oXML.LoadXml(sRawXML) ' This will generate an error if the Raw XML is malformed
oRootNode = oXML.ChildNodes(0)
Response.Write("Root node name is [" & oRootNode.Name & "]")
For Each oNode In oRootNode
Response.Write("Found Child node [" & oNode.Name & "]")
' Etc.
Next
Catch ex as System.Exception
Response.Write("<p>Your URL is junk, dude!")
End Try
End Sub
Private Function ReadURL(ByVal URL As String, ByVal UserId As String, ByVal Password As String, ByVal Domain As String) As String
Dim oRequest As New HTTPWeb.Request
' Create a new request credentials according to the user's input.
Dim oCred As New NetworkCredential(UserId, Password)
If Domain = [String].Empty Then
oCred = New NetworkCredential(UserName, Password)
Else
oCred = New NetworkCredential(UserName, Password, Domain)
End If
Try
oRequest.URL = URL
oRequest.UserId = UserId
oRequest.Password = Password
' You may need to add some credentials here (to do: strip out base from URL passed)
oRequest.AddCredential("https://www.yourserver.com/", "Negotiate")
oRequest.AddCredential("https://www.yourserver.com/", "Basic")
oRequest.AddCredential("https://www.yourserver.com/", "NTLM")
oRequest.AddCredential("https://www.yourserver.com/", "NTLMSSP")
oRequest.FormVars.Add("FormVar1", "1")
oRequest.FormVars.Add("FormVar2", "2")
oRequest.FormVars.Add("FormVar3", "3")
oRequest.Execute()
Return oRequest.Response
Catch ex As System.Exception
Return (ex.Message & vbCrLf & ex.StackTrace)
End Try
End Function
Then put this in a class module by itself
Code:
Imports System
Imports System.Net
Imports System.Threading
Imports System.Text
Imports System.IO
Imports System.Collections
Imports System.Collections.Specialized
Namespace HTTPWeb
Class Request
Protected allDone As New ManualResetEvent(False)
Private sResponse As String
Private sTarget As String
Private sPostData As String
Private oFormVars As System.Collections.Hashtable
Private sUserId As String
Private sPassword As String
Private sDomain As String
Private sCredentials As System.Collections.ArrayList
Private oCredentialCache As CredentialCache
Public Sub New()
oFormVars = New System.Collections.Hashtable
sTarget = ""
sPostData = ""
sResponse = ""
sUserId = ""
sPassword = ""
sDomain = ""
sCredentials = New System.Collections.ArrayList
oCredentialCache = Nothing
End Sub
Public Sub AddCredential(ByVal Site As String, ByVal Type As String)
Dim sItem(1, 2) As String
sItem(0, 0) = Site
sItem(0, 1) = Type
sCredentials.Add(sItem)
End Sub
Public Property CredentialCache() As CredentialCache
Get
Return oCredentialCache
End Get
Set(ByVal Value As CredentialCache)
oCredentialCache = Value
End Set
End Property
Public Property UserId() As String
Get
Return (sUserId)
End Get
Set(ByVal Value As String)
sUserId = Value
End Set
End Property
Public Property Password() As String
Get
Return ("**********")
End Get
Set(ByVal Value As String)
sPassword = Value
End Set
End Property
Public Property Domain() As String
Get
Return sDomain
End Get
Set(ByVal Value As String)
sDomain = Value
End Set
End Property
Property URL() As String
Get
Return sTarget
End Get
Set(ByVal Value As String)
sTarget = Value
End Set
End Property
ReadOnly Property FormVars() As System.Collections.Hashtable
Get
Return oFormVars
End Get
End Property
ReadOnly Property Response() As String
Get
Return (sResponse)
End Get
End Property
Public Sub Execute()
' Create a new HttpWebRequest object.
Dim oRequest As HttpWebRequest = CType(WebRequest.Create(sTarget), HttpWebRequest)
' Assign an instance of a System.Net.ICertificatePolicy for this application
' this is required to bypass the default return value for CheckValidationResult
' which is 'false'. This overrides the default behavior which causes all HTTPS over SSL
' to fail
ServicePointManager.CertificatePolicy = New ERSCertificateValidation
' Set the ContentType property.
oRequest.ContentType = "application/x-www-form-urlencoded"
' Set the Method property to 'POST' to post data to the URI.
oRequest.Method = "POST"
' Create the Credential Cache Object if user has not already
If oCredentialCache Is Nothing Then
oCredentialCache = New CredentialCache
If sCredentials.Count > 0 Then
Dim oNetworkCredential As New NetworkCredential(sUserId, sPassword)
Dim sItem(,) As String
For Each sItem In sCredentials
oCredentialCache.Add(New Uri(sItem(0, 0).ToString), sItem(0, 1).ToString, oNetworkCredential)
Next
End If
End If
oRequest.Credentials = oCredentialCache
' Force http request to authenticate if the userid is specified
oRequest.PreAuthenticate = (sUserId.Length > 0)
' Start the asynchronous operation.
Dim oResult As IAsyncResult = CType(oRequest.BeginGetRequestStream(AddressOf ReadCallback, oRequest), IAsyncResult)
' Keep the main thread from continuing while the asynchronous operation completes.
' A real world application could do something useful such as updating its user interface.
allDone.WaitOne()
' Get the response.
Dim response As HttpWebResponse = CType(oRequest.GetResponse(), HttpWebResponse)
Try
response = CType(oRequest.GetResponse(), HttpWebResponse)
Catch ex As System.Exception
Me.sResponse = "<br>Error while getting response"
Exit Sub
End Try
Dim streamResponse As Stream = response.GetResponseStream()
Dim streamRead As New StreamReader(streamResponse)
sResponse = streamRead.ReadToEnd()
' Close Stream object.
streamResponse.Close()
streamRead.Close()
' Release the HttpWebResponse.
response.Close()
End Sub ' Execute()
Private Sub ReadCallback(ByVal asynchronousResult As IAsyncResult)
Dim request As HttpWebRequest = CType(asynchronousResult.AsyncState, HttpWebRequest)
' End the operation.
Dim postStream As Stream = request.EndGetRequestStream(asynchronousResult)
Dim oEntry As System.Collections.DictionaryEntry
Dim sPostData As String
If oFormVars.Count > 0 Then
For Each oEntry In oFormVars
sPostData &= "&" & oEntry.Key & "=" & oEntry.Value.ToString
Next
sPostData = sPostData.Substring(1)
' Convert the string into byte array.
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(sPostData)
' Write to the stream.
postStream.Write(byteArray, 0, sPostData.Length)
postStream.Close()
End If
allDone.Set()
End Sub ' ReadCallback()
End Class
Public Class CertificateValidation
Implements System.Net.ICertificatePolicy
Public Function CheckValidationResult(ByVal sp As ServicePoint, ByVal cert As System.Security.Cryptography.X509Certificates.X509Certificate, ByVal req As WebRequest, ByVal problem As Integer) As Boolean Implements System.Net.ICertificatePolicy.CheckValidationResult
Return True
End Function
End Class
End Namespace
Hope this helps.
David McEnderfer
Senior Consultant