DateTime.TryParse returning wrong (IMO) answer - asp.net

I have an old asp classic VB script that was converted to run in VB .NET long ago that is a mess but I can't get approval to rewrite it yet.
In there it had a function that takes a string and attempts to handle it properly based on its content.
It was originally written as:
Public Shared Function fx(ByVal _str As String) As String
If IsDate(_str) Then
'Dates have to be formated just right for MySQL to accept them
fx = DatePart("yyyy", _str) & "-" & DatePart("m", _str) & "-" & DatePart("d", _str)
ElseIf IsNumeric(_str) Then
'Numbers go in just fine
fx = _str
ElseIf Len(_str) > 0 Then
'If it's not a date and not a number then treat it as a text field and filter it so that MySQL will take it
_str = Trim(_str) 'First trim off any leading and trailing spaces
_str = Replace(_str, "\", "\\") 'Change all \ to \\
_str = Replace(_str, "'", "''") 'Change all ' to ''
fx = _str
Else
fx = ""
End If
End Function
My problem comes when I use pass fx the value "11.16" and it says "Oh yes, that's a date - 2015/11/16"
I tried using success = DateTime.TryParse(_str,tempDate) but it behaves the same.
What is the best way to do this if _str being passed in can be anything from a blank string to a date to a dollar amount to a street address? The obvious is to rewrite the calling code but with the legacy code that's not terribly practical. Any suggestion appreciated.
Thanks!

Andrew Whitaker's answer of TryParseExact and an array of date formats is the best answer to my particular situation.

Public Shared Function fx(ByVal _str As String) As String
If IsDate(_str) Then
'Dates have to be formated just right for MySQL to accept them
fx = DatePart("yyyy", _str) & "-" & DatePart("m", _str) & "-" & DatePart("d", _str)
ElseIf IsNumeric(_str) Then
'Numbers go in just fine
fx = _str
ElseIf Len(_str) > 0 Then
'If it's not a date and not a number then treat it as a text field and filter it so that MySQL will take it
_str = Trim(_str) 'First trim off any leading and trailing spaces
_str = Replace(_str, "\", "\\") 'Change all \ to \\
_str = Replace(_str, "'", "''") 'Change all ' to ''
fx = _str
Else
fx = ""
End If
End Function

Related

Escaping apostrophe/single quote in parameterized sql in asp

I'm new to parametrized SQL. I've got a query in an .asp page that's getting one or more client names from a form. These are held in an array called clientArr and then passed through to SQL server as parameters. I'm escaping the ' as '' but this doesn't appear to be working. If I run the query with a client name like McDonald's, it returns no results.
clientArr(y) = Replace(clientArr(y),"'","''"
...
if qsClient > "" Then
dim booComma
booComma = false
if mySQLwhere > "" Then
mySQLwhere = mySQLwhere& " AND "
End if
mySQLwhere = mySQLwhere & " (p.client IN ( "
for y = 0 to Ubound(clientArr)
if booComma = true Then
mySQLwhere = mySQLwhere & ","
end if
mySQLwhere = mySQLwhere & "?"
booComma = true
Next
mySQLwhere = mySQLwhere & ")) "
end if
...
if qsClient > "" Then
for y = 0 to Ubound(clientArr)
Response.write clientArr(y)
set prm = cmd.CreateParameter("#prm", 129, 1, 50, clientArr(y))
cmd.Parameters.Append prm
next
end if
If I run the query directly or create it by concatenating strings rather then use parameters, it works fine. It also works fine is I use a client name without an apostrophe.
Any help would be much appreciated. Happy to provide more info if I can.
Thanks,
Tim
After working on this for far too long, it just hit me. Passing the parameter straight through like this means that I don't need to escape it at all. If I remove that replace statement, it works just fine keeping the single quote. I was definitely over-thinking this.

Save Base64 to an image using Classic ASP

I have been trying to save a base64 file as an image from server side using classic ASP. What I want is it to autosave the file to a specific location and give it a filename, Now I am fine coding that aspect of it. However I can't get the code to save the image without first rendering on a browser. This isn't going to work for me as the script I am using will be an automatic export and have no user input.
Code follows as yet that renders in the webpage and asks the user where to save the image. Just to reiterate I need it to auto save (no user input)
base64String ="base64 code goes here - Wont add it as its huge amount of text"
Set tmpDoc = Server.CreateObject("MSXML2.DomDocument")
Set nodeB64 = tmpDoc.CreateElement("b64")
nodeB64.DataType = "bin.base64" ' stores binary as base64 string
nodeB64.Text = Mid(base64String, InStr(base64String, ",") + 1) ' append data text (all data after the comma)
vehicleAuditName= "Audit1"
With Response
.Clear
.ContentType = "image/png"
.AddHeader "Content-Disposition", "attachment; filename=" & vehicleAuditName & ".png"
.BinaryWrite nodeB64.NodeTypedValue 'get bytes and write
.end
End With
use an adodb.stream object to store the image on the server side like so:
dim bStream : set bStream = server.CreateObject("ADODB.stream")
bStream.type = adTypeBinary
call bStream.Open()
call bStream.Write( binData )
call bStream.SaveToFile( FullName, adSaveCreateOverWrite)
call bStream.close()
set bStream = nothing
The server side code that receives the base64 string is below, please note that this is code that is taken from a working system so there are variables such as carreg / auditdate that are used as unique identifiers for giving the created file a name:
function convBase64 (convVal, getCarReg, convType, AuditDate, AuditReference)
base64String = convVal
carReg = (UCase(getCarReg))
carReg = (Replace(getCarReg," ",""))
AuditDate= CDate(AuditDate)
ConvAuditDate = ((DatePart("d",AuditDate))& "_" & (DatePart("m",AuditDate)) & "_" & (DatePart("YYYY",AuditDate)))
select case convType
Case "Sig1"
FileNameSuffix = "AuditorsSignature"
Case "Sig2"
FileNameSuffix = "BodyShopSignature"
Case "Car"
FileNameSuffix = "DamageCanvas"
end select
ImageFileName = FileNameSuffix & "-" & carReg & "-" & ConvAuditDate & ".jpg"
Set tmpDoc = Server.CreateObject("MSXML2.DomDocument")
Set nodeB64 = tmpDoc.CreateElement("b64")
nodeB64.DataType = "bin.base64" ' stores binary as base64 string
nodeB64.Text = Mid(base64String, InStr(base64String, ",") + 1) ' append data text (all data after the comma)
dim bStream : set bStream = server.CreateObject("ADODB.stream")
bStream.type = 1
call bStream.Open()
call bStream.Write( nodeB64.NodeTypedValue )
call bStream.SaveToFile(Server.Mappath("NoneVehicleImages/" & AuditReference & "/" & ImageFileName), 2 )
call bStream.close()
set bStream = nothing
convBase64 = "\\iis_fdg$\AuditExport\NoneVehicleImages\" & AuditReference & "\" & ImageFileName
end function
You cannot do this due to security reasons. If web pages could randomly choose where to store files on our local systems without any user interaction, there would chaos.

ASP Classic to VB.NET - Recursive Function including RecordSets

I'm hoping someone can help me think this one out because I'm stuck.
We are slowly migrating a ASP Classic web site to a .NET web application. I stumbled upon the following function. The function will return an array of strings that consists of hml a-tags.
Private Function getFullPathLinks(lNodeId, sPath, sDocTemplate)
Dim sql, recordSet, rsTmp
Dim arrPath, sResult
Dim lDocId
lDocId = getDocumentId(lNodeId)
sql = "SELECT parent_id, label FROM wt_node WHERE (node_id = " & lNodeId & ")"
Set recordSet = execSqlCache(oConn,sql,Array(),Array("wt_node"))
If Not (recordSet.Bof And recordSet.Eof) Then
If sDocTemplate <> "" Then
sPath = sPath & "|" & "<a href='" & sDocTemplate & "?nodeid=" & lNodeId & "&documentid=" & lDocId & "'>" & recordSet("label") & "</a>"
Else
sPath = sPath & "|" & recordSet("label")
End If
getFullPathLinks recordSet("parent_id"), sPath
End If
recordSet.Close
Set recordSet = Nothing
arrPath = arrReverse(Split(sPath,"|"))
sResult = Join(arrPath,sPathDelimiter)
If Right(sResult,Len(sPathDelimiter)) = sPathDelimiter Then sResult = Left(sResult,Len(sResult)-Len(sPathDelimiter))
getFullPathLinks = sResult
End Function
The function calls itself at the end and this will not work well in my .NET implementation where we are using DataReaders to talk to the SQL database.
Could I follow the same structure as above and instead use something else than a DataReader to achieve this?
I am not sure what SQL Server version you are using, but have you taken a look at recursive queries in SQL? It is designed to retrieve hierarchical data in a single db call. Take a look:
http://msdn.microsoft.com/en-us/library/ms186243(v=sql.105).aspx

Backslashes in path in VB.Net

It seems I'm not lucky with backslashes in ASP.Net VB.Net.
I'm trying to output some infos about files with ffprobe and my paths are cut randomly at some backslash in every string containing backslash.
I debugged this function to return the path generated by fileToProcess:
Function ffprobe_show_format(ByVal arg As String) As String
Dim myProcess As New System.Diagnostics.Process()
Dim fileToProcess As String = MapPath(".") & "\temps\" & arg
myProcess.StartInfo.FileName = MapPath(".") & "\ffprobe.exe"
myProcess.StartInfo.Arguments = "-show_format " & fileToProcess & " >C:\inetpub\vhosts\mysite.com\httpdocs\absolutefs\ffmpegtemp.txt"
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.RedirectStandardInput = True
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.Start()
Dim myStreamWriter As StreamWriter = myProcess.StandardInput
Dim mystreamreader As StreamReader = myProcess.StandardOutput
Dim str As String = mystreamreader.ReadToEnd
Return str & ";" & "FileToProcess=" & fileToProcess & "MapPath(.) AND ffprobe.exe" & MapPath(".") & "\\ffprobe.exe"
End Function
And it returns ;FileToProcess=C:
It means that
My file is not processed because of some errors
My Path is cut at backslashes
The rest of the string is then broken
Does I need to tell asp.net to represent backslashes in another way?
[EDIT]
I can't choose an answer but will upvote since I made two mistakes:
- To debug, I was reading my value once it was put in SQL variables with limites size then
- ... fetched with Newtonsoft.Json parser that probably was refusing some chars.
I'm new on ASP.Net so I have difficulties finding a good way to debug. So I finally made as usual when I'm not able to debug on a platform: I've written my debug vars in a text file, and everything was there using this way:
Function ffprobe_show_format(ByVal file As String, ByVal app As String) As String
Dim myProcess As New System.Diagnostics.Process()
myProcess.StartInfo.FileName = app
Dim argz As String = FormatCommandLine("-show_format", file)
myProcess.StartInfo.Arguments = argz
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.Start()
Dim mystreamreader As StreamReader = myProcess.StandardOutput str As String = mystreamreader.ReadToEnd
MapPath(".") & "/ffprobe.exe"
Dim objWriter As New System.IO.StreamWriter(MapPath(".") & "\debug.txt")
objWriter.Write(str)
objWriter.Close()
Return str
End Function
I'll add an ffmpeg tag since it's also another example on how to call it and process a file.
You don't need to worry about the backslashes. The backslash is not a special character in VB like it is in C#. In fact if you do double them up you might hit errors.
It's hard to tell where the problem is occurring. Some ideas to try to narrow it down:
Try not redirecting StandardInput since you aren't passing it anything.
Read from StandardError to make sure it is empty. It may contain an error message.
I would make use of Debug.WriteLine to trace the function and try to spot where things begin to go wrong.
This may not matter, but I would place myProcess.WaitForExit after mystreamreader.ReadToEnd.
Larry's suggestion to use System.IO.Path is a good one.
Some hastily modified code based on all this:
Function ffprobe_show_format(ByVal arg As String) As String
Debug.WriteLine("arg: " & arg)
Dim fileToProcess As String = IO.Path.Combine(MapPath("."), "temps\" & arg)
Debug.WriteLine("fileToProcess = " & fileToProcess)
Debug.WriteLine("MapPath AND ffprobe.exe: " & IO.Path.Combine(MapPath(".") & "\\ffprobe.exe"))
Dim myProcess As New System.Diagnostics.Process()
myProcess.StartInfo.FileName = IO.Path.Combine(MapPath("."), "\ffprobe.exe")
myProcess.StartInfo.Arguments = "-show_format " & fileToProcess & " >C:\inetpub\vhosts\mysite.com\httpdocs\absolutefs\ffmpegtemp.txt"
myProcess.StartInfo.UseShellExecute = False
'myProcess.StartInfo.RedirectStandardOutput = True
myProcess.StartInfo.RedirectStandardError = True
myProcess.Start()
'Dim str As String = myProcess.StandardOutput.ReadToEnd
Dim errStr as string = myProcess.StandardError.ReadToEnd
myProcess.WaitForExit()
Debug.WriteLine("myProcess exit code = " & myProcess.ExitCode.ToString())
'Debug.WriteLine("stdOutput: " & str)
Debug.WriteLine("stdError: " & errStr)
Return str & ";" & "FileToProcess=" & fileToProcess
End Function
There are a few things to consider here.
First, the back-slash character is the escape character (i.e. \t \n \r ...) and should be double-escaped \\ IF you MUST embed it into strings.
However, the .NET framework contains a very good class: System.IO.Path that has several Combine method overloads that can help you to construct paths without embedding back-slash characters into strings. This also makes your code more portable in the (somewhat unlikely) event that you would ever run it on a non-Windows platform.
http://msdn.microsoft.com/en-us/library/system.io.path
Try closing the StreamReader before accessing its contents:
Dim myStreamReader As StreamReader = myProcess.StandardOutput
Dim str As String = myStreamReader.ReadToEnd
myStreamReader.Close()
Return str & ";" & "FileToProcess=" & fileToProcess & "MapPath(.) AND ffprobe.exe" & MapPath(".") & "\\ffprobe.exe"
When I run your function in my local devbox:
Function ffprobe_show_format(ByVal arg As String) As String
Dim myProcess As New System.Diagnostics.Process()
Dim fileToProcess As String = HttpContext.Current.Server.MapPath(".") & "\temps\" & arg
myProcess.StartInfo.FileName = HttpContext.Current.Server.MapPath(".") & "\ffprobe.exe"
myProcess.StartInfo.Arguments = "-show_format " & fileToProcess & " >C:\inetpub\vhosts\mysite.com\httpdocs\absolutefs\ffmpegtemp.txt"
'myProcess.StartInfo.UseShellExecute = False
'myProcess.StartInfo.RedirectStandardInput = True
'myProcess.StartInfo.RedirectStandardOutput = True
'myProcess.Start()
'Dim myStreamWriter As StreamWriter = myProcess.StandardInput
'Dim myStreamReader As StreamReader = myProcess.StandardOutput
Dim str As String = String.Empty 'myStreamReader.ReadToEnd
Return str & ";" & "FileToProcess=" & fileToProcess & "MapPath(.) AND ffprobe.exe" & HttpContext.Current.Server.MapPath(".") & "\\ffprobe.exe"
End Function
I get what I consider to be a somewhat normal string returned for ffprobe_show_format:
";FileToProcess=C:\Documents and Settings\Me\My Documents\Proj1\SubApp1\temps\testMapPath(.) AND ffprobe.exeC:\Documents and Settings\Me\My Documents\Proj1\SubApp1\\"
I commented out the System.Diagnostics.Process() as I don't have an executable called ffprobe.exe.
Given that the rest of it works, Try closing the StreamReader before accessing its contents.
You should just need to escape each backslash with another backslash.
Or, you might be able to prefix your string with the # symbol (works in C#, not sure about VB.NET).
I.E.
instead of "C:\this\that.exe"
use "C:\this\that.exe"
or #"C:\this\that.exe"

Create (file) string with classic asp VBScript

In .net (C#) I use this to create a multiple file(name) string.
if (pic == null)
pic += "filename";
else
pic += "~" + "filename";
I'm unfamiliar with ASP.Classic VBScript.
Can someone help me with syntax in ASP.Classic VBScript?
Maybe this is what you want?
if pic = "" then
pic = pic & "filename"
else
pic = pic & "~" & "filename"
end if
Erik
You could do it like this.
If IsNull(pik) Then
pik = pik & "filename"
Else
pik = pik & "~" & "filename"
End If
Rico answer is correct as far as syntax is involved, however classic ASP does not recognize the ~ character as the web application root - this is new "feature" of ASP.NET that has no direct equivalent in classic ASP.
One way to get the root is using such function:
Function GetApplicationRoot()
Dim pathinfo, myRegExp
pathinfo = Request.ServerVariables("PATH_INFO")
Set myRegExp = New RegExp
myRegExp.IgnoreCase = True
myRegExp.Global = True
myRegExp.Pattern = "^(/\w*/).*"
GetApplicationRoot = myRegExp.Replace(pathinfo, "$1")
End Function
The above is based on the code found in this question.
Having this, the complete answer will be:
If Len(pic)=0 Then
pic = "filename"
Else
pic = pic & GetApplicationRoot() & "filename"
End If
Note that in VBScript, only empty database value will return Null all other strings will just be empty, meaning zero length.
In case pic is coming from database, change the code to:
blnNullOrEmpty = False
If IsNull(pic) Then
blnNullOrEmpty = True
Else
If Len(pic)=0 Then
blnNullOrEmpty = True
End If
End If
If blnNullOrEmpty Then
pic = "filename"
Else
pic = pic & GetApplicationRoot() & "filename"
End If

Resources