ASP Session variables: Is "" same as IsEmpty? - asp-classic

In ASP an uninitialized Session variable Is Empty. I know that the correct way to check for a Session value, and remove a value, is the following:
IF NOT IsEmpty(Session("myVar")) THEN
' Go ahead and use Session("myVar")
...
' Now if we're all done with myVar then remove it:
Session.Contents.Remove("myVar")
END IF
I've inherited a codebase where Application and Session variables are typically set = "" after use, and all tests for a value are of the form (Sessions("myVar") = ""). This test appears to work when the Session variable has not been declared ... or maybe it's just working by dumb luck.
Is it safe to use comparison with the empty string to test for a Session variable? I.e., is the following "practically as good" as the correct method shown above?
IF Session("myVar") <> "" THEN
' Go ahead and use Session("myVar")
...
' Now if we're all done with myVar then blank it:
Session("myVar") = ""
END IF
Or should I refactor the codebase so that:
All tests to determine whether a Session variable has been set are of the form IsEmpty(Session("myVar"))
All session variables are Removed and not set = ""?

Empty is a strange beast: it is simultaneously equal to both "" and 0. Seriously, try it:
dim x, y, z
x = Empty
y = ""
z = 0
Response.Write (x = y) AND (x = z)
It'll write out "True".
This means that testing for Not IsEmpty(myvar) is equivalent to testing myvar <> "", but IsEmpty(myvar) is not equivalent to myvar = "". Whether that mostly-theoretical difference bothers you or not is something only you can answer, but personally, I wouldn't waste time on refactoring.
If you do decide to refactor, I would suggest forgetting about IsEmpty and IsNull and whatnot, and just using the & "" "hack":
If Session("myvar") & "" <> "" Then
This'll transparently handle Nulls and Empties without you needing to write a whole bunch of code.

No, it could be not safe. Perhaps you need to use functions: IsNull, IsEmpty and VarType
IsNull -- returns True if expression is Null, that is, it contains no
valid data; otherwise, IsNull returns False. If expression consists of
more than one variable, Null in any constituent variable causes True
to be returned for the entire expression.
VarType -- Returns a value indicating the subtype of a variable.
IsEmpty -- returns True if the variable is uninitialized, or is
explicitly set to Empty; otherwise, it returns False. False is always
returned if expression contains more than one variable.
Please take a look at What is the '<>' asp operator?

Related

How to empty a multidimensional array?

I wrote an CSV import function. The CSV file gets seperated into columns and rows and is then saved into a multidimensional array.
At one point, I need to set the multidimensional array to Empty, because the following If-condition checks for IsEmpty().
I already tried this:
aMultidimArray = Empty
aMultidimArray = Nothing
ReDim aMultidimArray(0,0)
Erase aMultidimArray
a = Split(sData, sDelimiter)
For Each x In a
'*** Resize and write into multidimensional array
ReDim Preserve aMultidimArray(iFirstDim, iSecondDim)
aMultidimArray(i - 1,iSecondDim) = x
If (i = iFirstDim + 1) Then
i = 0
End If
i = i + 1
Next
'***Empty array here
???
'***
GetDataFromCSV = aMultidimArray
'**** other script
If IsEmpty(GetDataFromCSV) Then
Do stuff
End If
The IsEmpty(GetDataFromCSV) should return true, but I cannot handle it.
It is NOT about clearing the array. It's about getting it uninitialized again. If this is even possible.
As a workaround (or maybe just a better solution) I just called Exit function. As a result the return value is Emptyand the IsEmptycondition will return True.
When in doubt, read the documentation:
IsEmpty returns True if the variable is uninitialized, or is explicitly set to Empty; otherwise, it returns False. False is always returned if expression contains more than one variable.
Since your variable absolutely is initialized, even if you remove all values from the array, why would you expect IsEmpty to return anything but False?
Depending on what you actually want to achieve with your code you could check the dimensions of your array:
If UBound(GetDataFromCSV, 1) = -1 And UBound(GetDataFromCSV, 2) = -1 Then
'array is a 0x0 array
End If
If your array is not zero-sized you probably need to iterate over all fields and check if those are empty.
If you think you need to reset a variable that was defined as an array to Empty I suspect you made a design error somewhere, so I would strongly recommend to go back and fix the design. However, if you absolutely must reset an array variable to Empty for some reason you should be able to do so like this:
ReDim a(2, 5) 'define variable as array
...
Dim a 're-define variable as regular variable; does not clear the value
a = Empty 'clear variable

DbNull.Value and isDBNull for datacolumn

I have a DataRow which contain data from database. I want to check each data column for Null value in an IF condition.
I found two ways to check NULL value.
If IsDBNull(drType("ISShort")) Then
StartDate.Visible = True
Else
StartDate.Visible = False
End If
and
If Not drType("ISShort").ToString Is DBNull.Value Then
StartDate.Visible = True
Else
StartDate.Visible = False
End If
Both works fine for me but I don't know which one is better to use ?
I prefer DataRow.IsNull which returns a bool, is readable and efficient:
StartDate.Visible = drType.IsNull("ISShort")
related: Which of IsDBNull and IsNull should be used?
Note that your second approach doesn't work. If you convert it to String with ToString it can't be DBNull.Value. That compiles only with option-strict set to off which i strongly advise against.
Second case makes no sense as it does unnecessary ToString().
Note, there is another way you can use DbNull
If DbNull.Value.Equals(row.Item(fieldName)) Then
...
you can also use myDataRow.IsNull(fieldName) which is faster according to Which of IsDBNull and IsNull should be used?

What is the '<>' asp operator?

Simple question. I tried searching, by googling for less than and greater than signs doesn't return great results.
My guess is that <> is basically equivalent to not equals. So, the below expression would be false if x is null or an empty string, and true otherwise?
if x <> ""
This would also return True if a value is contained in the entity listed. This is commonly used to look for quesrystring or form elements that may or may not have been supplied:
If Request("someFieldName") <> "" Then
' Field was provided and has a value, so use the field value
Else
' Field was either empty or not provided, in which case use something else
End If
Hope this helps.
So, the below expression would be false if x is null or an empty string, and true otherwise?
Not exactly. There are few function to verify value:
IsNull(expression)
IsNull returns True if expression is Null, that is, it contains no
valid data; otherwise, IsNull returns False. If expression consists of
more than one variable, Null in any constituent variable causes True
to be returned for the entire expression.
The Null value indicates that the variable contains no valid data.
Null is not the same as Empty, which indicates that a variable has not
yet been initialized. It is also not the same as a zero-length string
(""), which is sometimes referred to as a null string.
IsEmpty(expression)
The expression argument can be any expression. However, because
IsEmpty is used to determine if individual variables are initialized,
the expression argument is most often a single variable name.
IsEmpty returns True if the variable is uninitialized, or is
explicitly set to Empty; otherwise, it returns False. False is always
returned if expression contains more than one variable.
Other good function
VarType(varname)
Returns a value indicating the subtype of a variable.
Use Windows Script 5.6 Documentation from http://www.microsoft.com/en-us/download/details.aspx?id=2764

Why won't this work as an IIF function, but will as an IF Statement?

The following works:
If 1=1
rdoYes.checked = True
Else
rdoNo.checked = True
End If
However, the following doesn't work:
IIF(1=1, rdoYes.checked = True, rdoNo.checked = True)
Why is this?
Thanks!
It does "work"; it just doesn't do what you want.
IIf in VB.NET is a function (don't use it, ever, by the way), which takes these parameters:
A Boolean condition to check
An Object to return if the condition is True
A different Object to return if the condition is False
In your usage, your condition is 1 = 1; then your two other parameters are rdoYes.Checked = True and rdoNo.Checked = True, both Boolean expressions from the VB compiler's perspective (so, really, they're equivalent to the simpler rdoYes.Checked and rdoNo.Checked).
Remember that in VB.NET, the = sign is only an assignment if it is on its own line. This is how the compiler distinguishes between statements such as x = 5 and If x = 5 Then.
This is not directly related to your question, but you should also be aware that IIf is deprecated and you should almost always favor If instead:
' Let us just suppose it made sense to write this: '
' Notice the If instead of IIf. '
Dim result = If(1 = 1, rdoYes.Checked, rdoNo.Checked)
The IIF() function will return something based on what you enter for the first parameter. Since VB.Net doesn't differ between = as in assignment and = as in comparison (== in many other languages), the second statement is ambiguous.
You can do this with using late binding (delegates in VB.Net):
(Function(c) InlineAssignHelper(c.Checked, true)).Invoke(IIf(1 = 1, chkYes, chkNo))
Private Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
target = value
Return value
End Function
Because IIf takes expressions and returns a result of one of them, and rdoYes.checked = True is not an expression and cannot be returned.
iif doesn't do what you think it does -- the important part is the return from it, so you might be able to do:
iif(1=1, rdoYes, rdoNo).checked = True
(I'm not sure that's valid VB ... it's been more than a decade since I've had to code in it)

VBScript conditional short-circuiting workaround

I have a large classic ASP app that I have to maintain, and I repeatedly find myself thwarted by the lack of short-circuit evaluation capability. E.g., VBScript won't let you get away with:
if not isNull(Rs("myField")) and Rs("myField") <> 0 then
...
...because if Rs("myField") is null, you get an error in the second condition, comparing null to 0. So I'll typically end up doing this instead:
dim myField
if isNull(Rs("myField")) then
myField = 0
else
myField = Rs("myField")
end if
if myField <> 0 then
...
Obviously, the verboseness is pretty appalling. Looking around this large code base, the best workaround I've found is to use a function the original programmer wrote, called TernaryOp, which basically grafts in ternary operator-like functionality, but I'm still stuck using a temporary variable that would not be necessary in a more full-featured language. Is there a better way? Some super-secret way that short-circuiting really does exist in VBScript?
Nested IFs (only slightly less verbose):
if not isNull(Rs("myField")) Then
if Rs("myField") <> 0 then
Maybe not the best way, but it certainly works... Also, if you are in vb6 or .net, you can have different methods that cast to proper type too.
if cint( getVal( rs("blah"), "" ) )<> 0 then
'do something
end if
function getVal( v, replacementVal )
if v is nothing then
getVal = replacementVal
else
getVal = v
end if
end function
I always used Select Case statements to short circuit logic in VB. Something like..
Select Case True
Case isNull(Rs("myField"))
myField = 0
Case (Rs("myField") <> 0)
myField = Rs("myField")
Case Else
myField = -1
End Select
My syntax may be off, been a while. If the first case pops, everything else is ignored.
If you write it as two inline IF statements, you can achieve short-circuiting:
if not isNull(Rs("myField")) then if Rs("myField") <> 0 then ...
But your then action must appear on the same line as well. If you need multiple statements after then, you can separate them with : or move your code to a subroutine that you can call. For example:
if not isNull(Rs("myField")) then if Rs("myField") <> 0 then x = 1 : y = 2
Or
if not isNull(Rs("myField")) then if Rs("myField") <> 0 then DoSomething(Rs("myField"))
Or perhaps I got the wrong end of the question. Did you mean something like iIf() in VB? This works for me:
myField = returnIf(isNothing(rs("myField")), 0, rs("myField"))
where returnIf() is a function like so:
function returnIf(uExpression, uTrue, uFalse)
if (uExpression = true) then returnIf = uTrue else returnIf = uFalse : end if
end function
Yeah it's not the best solution but what we use is something like this
function ReplaceNull(s)
if IsNull(s) or s = "" then
ReplaceNull = " "
else
ReplaceNull = s
end if
end function
Would that there were, my friend -- TernaryOp is your only hope.
Two options come to mind:
1) use len() or lenb() to discover if there is any data in the variable:
if not lenb(rs("myField"))=0 then...
2) use a function that returns a boolean:
if not isNothing(rs("myField")) then...
where isNothing() is a function like so:
function isNothing(vInput)
isNothing = false : vInput = trim(vInput)
if vartype(vInput)=0 or isEmpty(vInput) or isNull(vInput) or lenb(vInput)=0 then isNothing = true : end if
end function
You may be able to just use Else to catch nulls, ""s, etc.
If UCase(Rs("myField")) = "THING" then
'Do Things
elseif UCase(Rs("myField")) = "STUFF" then
'Do Other Stuff
else
'Invalid data, such as a NULL, "", etc.
'Throw an error, do nothing, or default action
End If
I've tested this in my code and it's currently working. Might not be right for everyone's situation though.

Resources