Is possible to add a String.contains more than one value? - asp.net

I want to make a control, when I create a companyId, to not permit to create id with special characters like, (&), (/), (), (ñ), ('):
If txtIdCompany.Text.Contains("&") Then
// alert error message
End If
But I can't do this:
If txtIdCompany.Text.Contains("&", "/", "\") Then
// alert error message
End If
How can I check more than one string in the same line?

You can use collections like a Char() and Enumerable.Contains. Since String implements IEnumerable(Of Char) even this concise and efficient LINQ query works:
Dim disallowed = "&/\"
If disallowed.Intersect(txtIdCompany.Text).Any() Then
' alert error message
End If
here's a similar approach using Enumerable.Contains:
If txtIdCompany.Text.Any(AddressOf disallowed.Contains) Then
' alert error message
End If
a third option using String.IndexOfAny:
If txtIdCompany.Text.IndexOfAny(disallowed.ToCharArray()) >= 0 Then
' alert error message
End If

If txtIdCompany.Text.Contains("&") Or txtIdCompany.Text.Contains("\") Or txtIdCompany.Text.Contains("/") Then
// alert error message
End If

Related

What if TinyURL API doesn't work..?

I have a vbscript function to create a tinyurl from a regular url.
FUNCTION GetShortURL(strUrl)
Dim oXml,strTinyUrl,strReturnVal
strTinyUrl = "http://tinyurl.com/api-create.php?url=" & strUrl
set oXml = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")
oXml.Open "GET", strTinyUrl, false
oXml.Send
strReturnVal = oXml.responseText
Set oXml = nothing
GetShortURL = strReturnVal
END FUNCTION
I have come across the problem when the tinyurl api is down or inaccessible, making my script fail:
msxml3.dll
error '80072efe'
The connection with the server was terminated abnormally
Is there a safeguard I can add to this function to prevent the error and use the long url it has..?
Many thanks in advance,
neojakey
If you want to just return strUrl if the call fails, you can use On Error Resume Next
FUNCTION GetShortURL(strUrl)
on error resume next
Dim oXml,strTinyUrl,strReturnVal
strTinyUrl = "http://tinyurl.com/api-create.php?url=" & strUrl
set oXml = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")
oXml.Open "GET", strTinyUrl, false
oXml.Send
strReturnVal = oXml.responseText
Set oXml = nothing
'Check if an error occurred.
if err.number = 0 then
GetShortURL = strReturnVal
else
GetShortURL = strUrl
end if
END FUNCTION
Obviously, you need some kind of error handling. In general, VBScript's error handling is no fun, but for your specs - get the right thing or the default in case of any/don't care what problem - you can use a nice and simple approach:
Reduce your original function to
assignment of default value to function name (to prepare for the failures)
On Error Resume Next (to disable VBScript's default error handling, i.e. crash)
assignment of the return value of a helper function to function name (to prepare for success)
In code:
Function GetShortURL2(strUrl)
GetShortURL2 = strUrl
On Error Resume Next
GetShortURL2 = [_getshorturl](GetShortURL2)
End Function
I use [] to be able to use an 'illegal' function name, because I want to emphasize that _getshorturl() should not be called directly. Any error in _getshorturl() will cause a skip of the assignment and a resume on/at the next line (leaving the function, returning the default, reset to default error handling).
The helper function contains the 'critical parts' of your original function:
Function [_getshorturl](strUrl)
Dim oXml : Set oXml = CreateObject("Msxml2.ServerXMLHTTP.3.0")
oXml.Open "GET", "http://tinyurl.com/api-create.php?url=" & strUrl, False
oXml.Send
[_getshorturl] = oXml.responseText
End Function
No matter which operation fails, the program flow will resume on/at the "End Function" line of GetShortURL2().
Added: Comments on the usual way to do it (cf. Daniel Cook's proposal)
If you switch off error handling (and "On Error Resume Next" is just that) you are on thin ice: all errors are hidden, not just the ones you recon with; your script will do actions in all the Next lines whether necessary preconditions are given or preparations done.
So you should either restrict the scope to one risky line:
Dim aErr
...
On Error Resume Next
SomeRiskyAction
aErr = Array(Err.Number, Err.Description, Err.Source)
On Error Goto 0
If aErr(0) Then
deal with error
Else
normal flow
End If
or check after each line in the OERN scope
On Error Resume Next
SomeRiskyAction1
If Err.Number Then
deal with error
Else
SomeRiskyAction2
If Err.Number Then
deal with error
Else
...
End If
End If
That's what I meant, when I said "no fun". Putting the risky code in a function will avoid this hassle.

converting code into classic asp

I want to convert the below string into classic asp code can any one help
email has some value but it is not going inside the Loop
Can any one help me.
If (IsEmpty(email) And IsNull(email)) Then
EndIf
The code looks like its VBScript already so there is no "conversion" needed, however the code is faulty. Should be:
If IsEmpty(email) Or IsNull(email) Then
End If
a variable cannot both be empty and contain a Null at the same time hence the orginal conditional expression was always false.
You could always try:
If IsEmpty(email) = True Then
'uninitialized
ElseIf IsNull(email) = True Then
'contains null value
ElseIf email = ""
'contains zero length string
Else
'Response.Write email
'MsgBox email
End If
In most cases I try to code so that the variable is guaranteed to be initialized so you don't need to run the IsEmpty check.
Option Explicit
Dim email
email = ""
Why don't you just check the length of the email variable:
If Len(Trim(email)) > 0 Then
Else
YOUR CODE HERE
End If

Problems with If Statement (ASP.NET)

Dim custEmail As String
Dim inputEmail As String
custEmail = dt.Rows(0).Item("email")
inputEmail = email_add.Text
if (custEmail.toString() == inputEmail.toString() ){
label1.Text = custEmail
}
End If
This code is giving an error: Compiler Error Message: BC30201: Expression expected.
I just basically want to check if two values are equal but its saying something about expression expected although i've given the expression to evaluate.
The above is a mix of vb.net and c# syntax. You can use either in .net with success but not both at the same time. Get rid of the { and } to stick with vb.
Looks like you are mixing C# and VB.Net. Assuming you are using VB.Net
Replace the '{' with Begin IF and remove the '}'.

Why is this looping infinitely?

So I just got my site kicked off the server today and I think this function is the culprit. Can anyone tell me what the problem is? I can't seem to figure it out:
Public Function CleanText(ByVal str As String) As String
'removes HTML tags and other characters that title tags and descriptions don't like
If Not String.IsNullOrEmpty(str) Then
'mini db of extended tags to get rid of
Dim indexChars() As String = {"<a", "<img", "<input type=""hidden"" name=""tax""", "<input type=""hidden"" name=""handling""", "<span", "<p", "<ul", "<div", "<embed", "<object", "<param"}
For i As Integer = 0 To indexChars.GetUpperBound(0) 'loop through indexchars array
Dim indexOfInput As Integer = 0
Do 'get rid of links
indexOfInput = str.IndexOf(indexChars(i)) 'find instance of indexChar
If indexOfInput <> -1 Then
Dim indexNextLeftBracket As Integer = str.IndexOf("<", indexOfInput) + 1
Dim indexRightBracket As Integer = str.IndexOf(">", indexOfInput) + 1
'check to make sure a right bracket hasn't been left off a tag
If indexNextLeftBracket > indexRightBracket Then 'normal case
str = str.Remove(indexOfInput, indexRightBracket - indexOfInput)
Else
'add the right bracket right before the next left bracket, just remove everything
'in the bad tag
str = str.Insert(indexNextLeftBracket - 1, ">")
indexRightBracket = str.IndexOf(">", indexOfInput) + 1
str = str.Remove(indexOfInput, indexRightBracket - indexOfInput)
End If
End If
Loop Until indexOfInput = -1
Next
End If
Return str
End Function
Wouldn't something like this be simpler? (OK, I know it's not identical to posted code):
public string StripHTMLTags(string text)
{
return Regex.Replace(text, #"<(.|\n)*?>", string.Empty);
}
(Conversion to VB.NET should be trivial!)
Note: if you are running this often, there are two performance improvements you can make to the Regex.
One is to use a pre-compiled expression which requires re-writing slightly.
The second is to use a non-capturing form of the regular expression; .NET regular expressions implement the (?:) syntax, which allows for grouping to be done without incurring the performance penalty of captured text being remembered as a backreference. Using this syntax, the above regular expression could be changed to:
#"<(?:.|\n)*?>"
This line is also wrong:
Dim indexNextLeftBracket As Integer = str.IndexOf("<", indexOfInput) + 1
It's guaranteed to always set indexNextLeftBracket equal to indexOfInput, because at this point the character at the position referred to by indexOfInput is already always a '<'. Do this instead:
Dim indexNextLeftBracket As Integer = str.IndexOf("<", indexOfInput+1) + 1
And also add a clause to the if statement to make sure your string is long enough for that expression.
Finally, as others have said this code will be a beast to maintain, if you can get it working at all. Best to look for another solution, like a regex or even just replacing all '<' with <.
In addition to other good answers, you might read up a little on loop invariants a little bit. The pulling out and putting back stuff to the string you check to terminate your loop should set off all manner of alarm bells. :)
Just a guess, but is this like the culprit?
indexOfInput = str.IndexOf(indexChars(i)) 'find instance of indexChar
Per the Microsoft docs, Return Value -
The index position of value if that string is found, or -1 if it is not. If value is Empty, the return value is 0.
So perhaps indexOfInput is being set to 0?
What happens if your code tries to clean the string <a?
As I read it, it finds the indexChar at position 0, but then indexNextLeftBracket and indexRightBracket both equal 0, you fall into the else condition, and then you insert a ">" at position -1, which will presumably insert at the beginning, giving you the string ><a. The new indexRightBracket then becomes 0, so you delete from position 0 for 0 characters, leaving you with ><a. Then the code finds the <a in the code again, and you're off to the races with an infinite memory-consuming loop.
Even if I'm wrong, you need to get yourself some unit tests to reassure yourself that these edge cases work properly. That should also help you find the actual looping code if I'm off-base.
Generally speaking though, even if you fix this particular bug, it's never going to be very robust. Parsing HTML is hard, and HTML blacklists are always going to have holes. For instance, if I really want to get a <input type="hidden" name="tax" tag in, I'll just write it as <input name="tax" type="hidden" and your code will ignore it. Your better bet is to get an actual HTML parser involved, and to only allow the (very small) subset of tags that you actually want. Or even better, use some other form of markup, and strip all HTML tags (again using a real HTML parser of some description).
I'd have to run it through a real compiler but the mindpiler tells me that the str = str.Remove(indexOfInput, indexRightBracket - indexOfInput) line is re-generating an invalid tag such that when you loop through again it finds the same mistake "fixes" it, tries again, finds the mistake "fixes" it, etc.
FWIW heres a snippet of code that removes unwanted HTML tags from a string (It's in C# but the concept translates)
public static string RemoveTags( string html, params string[] allowList )
{
if( html == null ) return null;
Regex regex = new Regex( #"(?<Tag><(?<TagName>[a-z/]+)\S*?[^<]*?>)",
RegexOptions.Compiled |
RegexOptions.IgnoreCase |
RegexOptions.Multiline );
return regex.Replace(
html,
new MatchEvaluator(
new TagMatchEvaluator( allowList ).Replace ) );
}
MatchEvaluator class
private class TagMatchEvaluator
{
private readonly ArrayList _allowed = null;
public TagMatchEvaluator( string[] allowList )
{
_allowed = new ArrayList( allowList );
}
public string Replace( Match match )
{
if( _allowed.Contains( match.Groups[ "TagName" ].Value ) )
return match.Value;
return "";
}
}
That doesn't seem to work for a simplistic <a<a<a case, or even <a>Test</a>. Did you test this at all?
Personally, I hate string parsing like this - so I'm not going to even try figuring out where your error is. It'd require a debugger, and more headache than I'm willing to put in.

How do you call a method from a variable in ASP Classic?

For example, how can I run me.test below?
myvar = 'test'
me.myvar
ASP looks for the method "myvar" and doesn't find it. In PHP I could simply say $me->$myvar but ASP's syntax doesn't distinguish between variables and methods. Suggestions?
Closely related to this, is there a method_exists function in ASP Classic?
Thanks in advance!
EDIT: I'm writing a validation class and would like to call a list of methods via a pipe delimited string.
So for example, to validate a name field, I'd call:
validate("required|min_length(3)|max_length(100)|alphanumeric")
I like the idea of having a single line that shows all the ways a given field is being validated. And each pipe delimited section of the string is the name of a method.
If you have suggestions for a better setup, I'm all ears!
You can achieve this in VBScript by using the GetRef function:-
Function Test(val)
Test = val & " has been tested"
End Function
Dim myvar : myvar = "Test"
Dim x : Set x = GetRef(myvar)
Response.Write x("Thing")
Will send "Thing has been tested" to the client.
So here is your validate requirement using GetRef:-
validate("Hello World", "min_length(3)|max_length(10)|alphanumeric")
Function required(val)
required = val <> Empty
End Function
Function min_length(val, params)
min_length = Len(val) >= CInt(params(0))
End Function
Function max_length(val, params)
max_length = Len(val) <= CInt(params(0))
End Function
Function alphanumeric(val)
Dim rgx : Set rgx = New RegExp
rgx.Pattern = "^[A-Za-z0-9]+$"
alphanumeric = rgx.Test(val)
End Function
Function validate(val, criterion)
Dim arrCriterion : arrCriterion = Split(criterion, "|")
Dim criteria
validate = True
For Each criteria in arrCriterion
Dim paramListPos : paramListPos = InStr(criteria, "(")
If paramListPos = 0 Then
validate = GetRef(criteria)(val)
Else
Dim paramList
paramList = Split(Mid(criteria, paramListPos + 1, Len(criteria) - paramListPos - 1), ",")
criteria = Left(criteria, paramListPos - 1)
validate = GetRef(criteria)(val, paramList)
End If
If Not validate Then Exit For
Next
End Function
Having provided this I have to say though that if you are familiar with PHP then JScript would be a better choice on the server. In Javascript you can call a method like this:-
function test(val) { return val + " has been tested"; )
var myvar = "test"
Response.Write(this[myvar]("Thing"))
If you are talking about VBScript, it doesn't have that kind of functionality. (at least not to my knowledge) I might attempt it like this :
Select myvar
case "test":
test
case "anotherSub":
anotherSub
else
defaultSub
end select
It's been a while since I wrote VBScript (thank god), so I'm not sure how good my syntax is.
EDIT-Another strategy
Personally, I would do the above, for security reasons. But if you absolutely do not like it, then you may want to try using different languages on your page. I have in the past used both Javascript AND VBScript on my Classic ASP pages (both server side), and was able to call functions declared in the other language from my current language. This came in especially handy when I wanted to do something with Regular Expressions, but was in VBScript.
You can try something like
<script language="vbscript" runat="server">
MyJavascriptEval myvar
</script>
<script language="javascript" runat="server">
function MyJavascriptEval( myExpression)
{
eval(myExpression);
}
/* OR
function MyJavascriptEval( myExpression)
{
var f = new Function(myExpression);
f();
}
*/
</script>
I didn't test this in a classic ASP page, but I think it's close enough that it will work with minor tweaks.
Use the "Execute" statement in ASP/VBScript.
Execute "Response.Write ""hello world"""
PHP's ability to dynamically call or create functions are hacks that lead to poor programming practices. You need to explain what you're trying to accomplish (not how) and learn the correct way to code.
Just because you can do something, doesn't make it right or a good idea.
ASP does not support late binding in this manner. What are you trying to do, in a larger sense? Explain that, and someone can show you how to accomplish it in asp.
Additionally, you might consider "objectifying" the validation functionality. Making classes is possible (though not widely used) in VB Script.
<%
Class User
' declare private class variable
Private m_userName
' declare the property
Public Property Get UserName
UserName = m_userName
End Property
Public Property Let UserName (strUserName)
m_userName = strUserName
End Property
' declare and define the method
Sub DisplayUserName
Response.Write UserName
End Sub
End Class
%>

Resources