Free Code – Class to read URL name-value pairs

Here is another little code snippet I want to share. I use it all the time in my Lotusscript-based Domino web agents, and I figured that other could benefit from it as well. It is just an easy way to check for and read the name-value pairs (arguments) passed from the browser to the web server by HTTP GET or POST calls.

Put the code below in a script library, I call it Class.URL:

%REM
	Library Class.URL
	Created Oct 9, 2014 by Karl-Henry Martinsson
	Description: Lotusscript class to handle incoming URL (GET/POST).
%END REM
Option Public
Option Declare

%REM
	Class URLData
	Description: Class to handle URL data passed to web agent
%END REM
Class URLData
	p_urldata List As String
	
	%REM
		Sub New()
		Description: Create new instance of URL object from NotesDocument 
	%END REM
	Public Sub New()
		Dim session As New NotesSession
		Dim webform As NotesDocument
		Dim tmp As String
		Dim tmparr As Variant  
		Dim tmparg As Variant
		Dim i As Integer
		
		'*** Get document context (in-memory NotesDocument)
		Set webform = session.DocumentContext
		'*** Get HTTP GET argument(s) after ?OpenAgent
		tmp = FullTrim(StrRight(webform.GetItemValue("Query_String")(0),"&"))
		If tmp = "" Then
			'*** Get HTTP POST argument(s) after ?OpenAgent
			tmp = FullTrim(StrRight(webform.GetItemValue("Request_Content")(0),"&"))	
		End If
		'*** Separate name-value pairs from each other into array
		tmparr = Split(tmp,"&")		 
		'*** Loop through array, split each name-value/argument 
		For i = LBound(tmparr) To UBound(tmparr)
			tmparg = Split(tmparr(i),"=")
			p_urldata(LCase(tmparg(0))) = Decode(tmparg(1))
		Next
	End Sub
	
	%REM
		Function GetValue
		Description: Get value for specified argument.
		Returns a string containing the value.
	%END REM
	Public Function GetValue(argname As String) As String
		If IsElement(p_urldata(LCase(argname))) Then
			GetValue = p_urldata(LCase(argname))
		Else		
			GetValue = ""	
		End If
	End Function
	
	%REM
		Function IsValue
		Description: Check if specified argument was passed in URL or not.
		Returns boolean value (True or False).
	%END REM
	Public Function IsValue(argname As String) As Boolean
		If IsElement(p_urldata(LCase(argname))) Then
			IsValue = True
		Else		
			IsValue = False	
		End If
	End Function
	
	
	'*** Private function for this class
	'*** There is no good/complete URL decode function in Lotusscript
	Private Function Decode(txt As String) As String
		Dim tmp As Variant 
		Dim tmptxt As String
		tmptxt = Replace(txt,"+"," ")
		tmp = Evaluate(|@URLDecode("Domino";"| & tmptxt & |")|)
		Decode = tmp(0)
	End Function
	
End Class

It is now very easy to use the class to check what values are passed to the agent. Below is a sample agent:

Option Public
Option Declare
Use "Class.URL"

Sub Initialize
    Dim url As URLData

    '*** Create new URLData object
    Set url = New URLData()

    '*** MIME Header to tell browser what kind of data we will return
    Print "content-type: text/html"

    '*** Check reqired values for this agent
    If url.IsValue("name")=False Then
        Print "Missing argument 'name'."
        Exit Sub
    End If

    '*** Process name argument
    If url.GetValue("name")="" Then
        Print "'Name' is empty."
    Else
        Print "Hello, " + url.GetValue("name") + "!"
    End If

End Sub

It is that easy.

If my proposal for a session at ConnectED is accepted, you will about how to use jQuery and Bootstrap to retrieve data in .NSF databases through Lotusscript agents, and I will be using this class in my demos. So see this as a preview.
If the session doesn’t get selected by IBM, I plan to record it and post it somewhere online later.

The premise of the session is that you have data in a Domino database, but for some reason you can’t use XPages. Your company may be on an older version of Notes/Domino with no plans/budget to upgrade, the web developer don’t know XPage and have no time to learn it, or the data will be retreived from some other Web based system, perhaps WordPress.

Update: The session was not accepted at ConnectED, but I will present it at WMLUG in Atlanta on August 19, 2015.

This Post Has 4 Comments

  1. Howard

    No XPages? What a nightmare!

    1. Karl-Henry Martinsson

      There are companies in that situation… Stuck on 8.5 or even older versions. 🙁

  2. Nick Wall

    We use a similar technique for the Lotusscript portion of our app, but on large POST @UrlDecode() will error if the Len(your data) > 2048. We got around it using a technique that I don’t think is great, but works for us: we split(our data;” “) then iterate over the array and decode each bit and stick back together. Not great, but if anyone has any better ideas…?

    1. Karl-Henry Martinsson

      I think there are few fields/values that are that large, but in that case, your solution is pretty clever. I would improve it by splitting the data at say 2000 characters (round down to closest space), so you have fewer values to process.

Leave a Reply