Copying cookies across domains in ASP.Net

If you logging in to remote sites using HttpWebRequest then you are probably used to supplying a CookieContainer object to keep track of login sessions etc. However, sometimes a login will do a redirect, leaving your cookies referring to the login url and not usable on the next url.

Post login details to
Site redirects (302) to:

The login cookie is stuck on http://yourdomain/login and is not used at http://yourdomain/admin, so the login fails.

The key is to set:
WebRequestObject.AllowAutoRedirect = false
in the HttpWebRequest for http://yourdomain/login

Code to copy cookies:

Dim oOldCookies As New CookieContainer
Dim oNewCookies As New CookieContainer
Dim oOldCookiesCol As New CookieCollection

'Do HttpRequest on http://yourdomain/login, place cookies in oOldCookies
'Remember to set WebRequestObject.AllowAutoRedirect = false

oOldCookiesCollection = oOldCookies.GetCookies(New System.Uri(""))
For iC = 0 To oOldCookiesCol.Count - 1
     oNewCookies.Add(New Cookie(oOldCookiesCol(iC).Name, oOldCookiesCol(iC).Value, "", ""))

'Now do HttpRequest on http://yourdomain/admin, using oNewCookies

This post brought to you by - Over 10,000 Aged domains for sale!

Related posts:

  1. Easy Cross Domain Cookies (Sharing cookies between domains)
  2. How to set third-party cookies with iframe Facebook Applications
  3. Opening a new browser window with POST data
  4. SEOMoz Linkscape API wrapper in VB.Net

Getting Flights info from the Kayak API in ASP.Net

Kayak is one of the top travel meta-search engines on the web, and they have a free API which allows you to get flight and hotel information.

To use the Kayak API, first get a developer key

Then you can read the full specifications to get the info. Or, just use the code below :)

This gets the flights given an Origin, Destination, Departure date and the number of travellers (note: Origin & Destination must be in the form of a 3 letter Airport code, eg: MEL = Melbourne, SYD = Sydney, LAX = Los Angeles).

You can also Download the full source code

        Private Function Flights(ByVal dtDepartDate As Date, _
                ByVal sOriginCode As String, _
                ByVal sDestinationCode As String, _
                ByVal iTravellers As Integer) As DataTable

                Dim sResult As String
                Dim oCookies As New CookieContainer
                Dim sURL As String
                Dim oDoc As New System.Xml.XmlDocument
                Dim sSID As String
                Dim sSearchID As String
                Dim bMorePending As Boolean = True
                Dim oTripList As System.Xml.XmlNodeList
                Dim oTrip As System.Xml.XmlNode
                Dim oFlights As DataTable
                Dim oFlight As DataRow
                Dim iFlightsFound As Integer
                Dim sDeveloperKey As String = "***Your Key Here****"

                'Full specs at:

                'Get the SessionID
                sURL = "" & sDeveloperKey
                sResult = sGetData(sURL, oCookies)
                sSID = oDoc("ident")("sid").InnerText

                'Start the Flight Search & get the SearchID
                sURL = "" & _
                "basicmode=true&oneway=y" & _
                "&origin=" & sOriginCode & _
                "&destination=" & sDestinationCode & _
                "&depart_date=" & Format(dtDepartDate, "MM/dd/yyyy") & _
                "&depart_time=a&" & _
                "return_date=" & _
                "&return_time=a" & _
                "&travelers=" & iTravellers & _
                "&cabin=b&action=doflights&apimode=1&_sid_=" & sSID
                sResult = sGetData(sURL, oCookies)
                sSearchID = oDoc("search")("searchid").InnerText

                oFlights = dtFlightsTableInit()

                Do While bMorePending = True
                        'Get the first lot of results
                        sURL = "" & _
                        "searchid=" & sSearchID & _
                        "&c=10&apimode=1&_sid_=" & sSID
                        sResult = sGetData(sURL, oCookies)
                        bMorePending = IIf(oDoc("searchresult")("morepending").InnerText = "true", True, False)
                        If bMorePending = True Then
                                'Wait for 5 seconds, then poll again
                                System.Threading.Thread.Sleep(5 * 1000)
                        End If
                iFlightsFound = Val(oDoc("searchresult")("count").InnerText)

                'Build the final request, asking for the total number of flights found by
                sURL = "" & _
                "searchid=" & sSearchID & _
                "&c=" & iFlightsFound & _
                "&apimode=1&_sid_=" & sSID
                sResult = sGetData(sURL, oCookies)

                oTripList = oDoc.SelectNodes("//trip")
                For Each oTrip In oTripList
                        oFlight = oFlights.NewRow()
                        oFlight("DepartDate") = oTrip("legs")("leg")("depart").InnerText
                        oFlight("ArriveDate") = oTrip("legs")("leg")("arrive").InnerText
                        oFlight("Airline") = oTrip("legs")("leg")("airline_display").InnerText
                        oFlight("Price") = oTrip("price").InnerText
                        oFlight("BookURL") = oTrip("price").Attributes("url").Value

                Flights = oFlights
        End Function

        Public Function dtFlightsTableInit() As DataTable
                Dim dtFlights As New DataTable

                dtFlights.Columns.Add(New DataColumn("DepartDate", GetType(String)))
                dtFlights.Columns.Add(New DataColumn("ArriveDate", GetType(String)))
                dtFlights.Columns.Add(New DataColumn("Airline", GetType(String)))
                dtFlights.Columns.Add(New DataColumn("Price", GetType(String)))
                dtFlights.Columns.Add(New DataColumn("BookURL", GetType(String)))

                dtFlightsTableInit = dtFlights
        End Function

        Public Function sGetData(ByVal sURL As String, _
Optional ByRef oCookies As CookieContainer = Nothing) As String

                Dim Writer As StreamWriter = Nothing
                Dim WebRequestObject As HttpWebRequest
                Dim sr As StreamReader
                Dim WebResponseObject As HttpWebResponse
                Dim sbResultsBuilder As New StringBuilder
                Dim sBuffer(8192) As Char
                Dim iRetChars As Integer

                WebRequestObject = CType(WebRequest.Create(sURL), HttpWebRequest)
                WebRequestObject.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"
                WebRequestObject.Method = "GET"
                WebRequestObject.Timeout = 55000
                WebRequestObject.ReadWriteTimeout = 55000
                WebRequestObject.AllowAutoRedirect = True

                If Not (oCookies Is Nothing) Then
                        WebRequestObject.CookieContainer = oCookies
                End If

                WebResponseObject = CType(WebRequestObject.GetResponse(), HttpWebResponse)

                sr = New StreamReader(WebResponseObject.GetResponseStream)

                        iRetChars = sr.Read(sBuffer, 0, sBuffer.Length)
                        If iRetChars > 0 Then
                                sbResultsBuilder.Append(sBuffer, 0, iRetChars)
                        End If
                Loop While iRetChars > 0
                sGetData = sbResultsBuilder.ToString

        End Function

The Kayak API is pretty good, but does have some limitations, so I think is works best when you use it for stats rather than bookings. Anyone else know of some good travel APIs?

This post brought to you by - Over 10,000 Aged domains for sale!

Related posts:

  1. SEOMoz Linkscape API wrapper in VB.Net
  2. Create a Website Comparison Widget using GoogleTrends
  3. Using to Generate Truly Random Numbers in .Net
  4. Allowing special characters (forward slash, hash, asterisk etc) in ASP.Net MVC URL parameters