Request.QueryString And Request.ServerVariables("QUERY_STRING") Not Displaying UNICODE - unicode

I'm adding logging functionality to a Classic ASP application and am having difficulty getting Request.QueryString and Request.ServerVariables to display correctly when users submit UNICODE queries.
For example -
Response.write Request.QueryString
strVar1=&strVar2=%E8%A1%8C%E9%9B%B2%E6%B5%81%E6%B0%B4&strVar3=blah1&strVar4=blah2
Response.write Request.ServerVariables("QUERY_STRING")
strVar1=&strVar2=%E8%A1%8C%E9%9B%B2%E6%B5%81%E6%B0%B4&strVar3=blah1&strVar4=blah2
Yet if I specify a UNICODE variable in Request.QueryString it prints correctly:
Response.write Request.QueryString("strVar2")
行雲流水
How can I get Request.QueryString or Request.ServerVariables("QUERY_STRING") to include UNICODE? I do have the following on both my search and results pages and queries execute successfully against the database:
<%
Response.CodePage = 65001
Response.CharSet = "utf-8"
%>
To answer bobince's question, I'm trying to log search terms and pages from which they're submitted - if there's a better way to do this I'm all ears:
'Enable Logging: writes to MyDB.dbo.logging
'---------------------------------------------------------------------------------------------
Set cmd = Server.CreateObject("ADODB.Command")
cmd.CommandType = adCmdText
cmd.ActiveConnection = objConn
strADName = UCase(Request.ServerVariables("AUTH_USER"))
Protocol = Request.ServerVariables("SERVER_PROTOCOL")
Protocol = Left(Protocol,InStr(Request.ServerVariables("SERVER_PROTOCOL"),"/")-1)
if Request.ServerVariables("SERVER_PORT") = "80" then
port = ""
else
port = ":" & Request.ServerVariables("SERVER_PORT")
end if
CurPageURL = lcase(Protocol) & "://" & Request.ServerVariables("SERVER_NAME") &_
port & Request.ServerVariables("SCRIPT_NAME") & "?" & _
Request.ServerVariables("QUERY_STRING")
strSQL = "INSERT INTO MyDB.dbo.Logging([user],URL) SELECT ?, ? "
cmd.Parameters.Append (cmd.CreateParameter("User", adVarWChar, adParamInput, len(strADName), strADName))
cmd.Parameters.Append (cmd.CreateParameter("URL", adVarWChar, adParamInput, len(CurPageURL), CurPageURL))
cmd.CommandText = strSQL
set objRS = cmd.Execute
'-----------------------------------------------------------------------------------------------

This isn't really anything to do with Unicode.
Request.QueryString does two separate things.
If you use it without arguments, it returns the whole query string exactly as submitted by the browser (as above, the same as the QUERY_STRING server variable).
If you use it with an argument like "strVar2", it splits up the query string into parameter parts, finds the one(s) that correspond to the argument name (strVar2=...), and returns the value. In doing so it takes care of URL-decoding the components of the query string including the name and the value, so the %xx sequences in the input are decoded to the byte sequence they represent: 0xE8, 0xA1, 0x8C and so on. When you print that byte string to a page that a browser decodes as UTF-8, they will see 行雲流水.
You can do a URL-decode step yourself on the full query string if you really want. There isn't a built-in for URL-decoding in Classic ASP but you can write such a function yourself (see eg URLDecode from http://www.aspnut.com/reference/encoding.asp), or use
decodeURIComponent(s.replace(/\+/g, ' '))
from JScript.
Note that if you URL-decode a whole URL string together you are kind of breaking it. For example for input query string:
foo=abc%26def&bar=%e6%97%a5%e6%9c%ac%e8%aa%9e
you would get:
foo=abc&def&bar=日本語
which is fine for the Japanese, but the ampersand in the value for foo has broken the whole string so you can no longer tell for sure what the original parameters were. You should generally only decode URL components once you have split them up from the URL they came in. This is what ASP does for you: Request.QueryString("foo") would correctly return abc&def here which is why you should almost always be using that method to retrieve parameters.
What exactly are you trying to do by decoding a whole query string?

In case this can help someone else:
I resolved this by extracting variable names from QUERY_STRING using the split function with & as the delimiter. I then used the variables with Request.QueryString to get the values, including ones with UNICODE. This works unless the user includes & in the query, which will be pretty rare. I do trap for it so at least in that case I can still see the user and page accessed in the logs. Bobince your response was excellent and I will select it as the answer.
'Enable Logging: writes to MyDB.dbo.logging
'---------------------------------------------------------------------------------------------
Set cmd = Server.CreateObject("ADODB.Command")
cmd.CommandType = adCmdText
cmd.ActiveConnection = objConn
cmd.CommandTimeOut = 1200
strADName = UCase(Request.ServerVariables("AUTH_USER"))
Protocol = Request.ServerVariables("SERVER_PROTOCOL")
Protocol = Left(Protocol,InStr(Request.ServerVariables("SERVER_PROTOCOL"),"/")-1)
if Request.ServerVariables("SERVER_PORT") = "80" then
port = ""
else
port = ":" & Request.ServerVariables("SERVER_PORT")
end if
CurPageURL = lcase(Protocol) & "://" & Request.ServerVariables("SERVER_NAME") &_
port & Request.ServerVariables("SCRIPT_NAME") & "?"
On Error Resume Next
a = Request.ServerVariables("QUERY_STRING")
a = split(a,"&")
for each x in a
'response.write(left(x,InStr(x,"=")-1) & "<br />")
CurPageURL = CurPageURL + left(x,InStr(x,"=")-1) + "=" + Request.QueryString(left(x,InStr(x,"=")-1)) & "&"
next
If Err.Number <> 0 Then
CurPageURL = CurPageURL + "Error: Search Term Contained a &"
Err.Clear
Else
CurPageURL = left(CurPageURL,len(CurPageURL)-1)
End If
strSQL = "INSERT INTO MyDB.dbo.Logging([user],URL) SELECT ?, ? "
cmd.Parameters.Append (cmd.CreateParameter("User", adVarWChar, adParamInput, len(strADName), strADName))
cmd.Parameters.Append (cmd.CreateParameter("URL", adVarWChar, adParamInput, len(CurPageURL), CurPageURL))
cmd.CommandText = strSQL
set objRS = cmd.Execute

Related

Acces ODBC passthru query fails with error 3146 giving different error description texts

I create a passthru query SELECTINg rows of a Postgres v.11 database table.
Running currentDb.execute generates ODBC error 3146 and "invalid argument" mentioned in DBEngine.errors.
Opening same query in the database explorer generates ODBC error 3146 and a message box with "permission denied ..." which actually reflects the source of error.
My questions is how can I programmatically get hold of latter more informative error message ?
I think the following will provide what you are looking for:
Public Function DbEngineErrors() As String
Dim intErr As Integer
Dim strRet As String
Dim strErr As String
If DBEngine.Errors.Count > 0 Then
strRet = "DbEngineErrors:"
For intErr = 0 To DBEngine.Errors.Count - 1
strErr = DBEngine.Errors(intErr).Number & " / " & DBEngine.Errors(intErr).Description & " / " & DBEngine.Errors(intErr).Source
strRet = strRet & vbCrLf & strErr
Next
End If
DbEngineErrors = strRet
End Function

Printers object in VB 6 not returning printer with special character in name

VB6 (not VB.Net or VBScript)
I'm using the Printer object and recently found that some printers
are not being returned if the name has certain characters.
In VB6 it would be something like:
Dim pr As Printer
For Each pr In Printers
MsgBox pr.DeviceName
Next pr
I can easily rename any printer in Windows (any OS version) and
make it fail.
I suspect it's related to a UTF-8/Unicode issue, but I don't know how to resolve it.
For example, this printer name works fine: "MyPrinter 1", but this does not: "MyPrinter 1 ę".
How can I get the Printer when the name has a non-standard (for US English anyway) character?
EDIT:
I've found this code to access the printers, and it will correctly return all of them, even with special characters.
However, I don't know how to either:
1) Use the object for printing (as I would with a Printers object)
2) Or set a Printer object to the returned object from WMI
(FYI - The InkEdit control will correctly show the special characters without any Unicode wrangling - I'm using for display purposes only.)
Dim strComputer As String
Dim objWMIService As Object
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPrinters = objWMIService.ExecQuery ("Select * from Win32_Printer")
Dim myPrinter As Printer
Dim junk As String
For Each objprinter In colInstalledPrinters
List1.AddItem objprinter.Name & " --- " & objprinter.ShareName & " --- " & objprinter.ServerName
InkEdit1.Text = InkEdit1.Text & objprinter.Name & " --- " & objprinter.ShareName & " --- " & objprinter.ServerName & vbNewLine
If InStr(1, objprinter.Name, "HP") > -1 Then
myPrinter = objprinter.
End If
Next

How to replace a special character in email body with a value in each row using Excel with VBA to multiple recipients

I am creating an Excel UserForm that creates a separate email for up to 500 recipients.
There are 4 columns on the worksheet: Name(Column A), Email(Column B), Value 1(Column C).
The code uses the For and Next loop style, where r is declared as an Integer (r = 2 To 500) and with the MailItem Object, .To =Cells(r,2).
The issue I have is attempting to incorporate values from a range (Column C) that replace special characters placed in the text box used to create the body of the email.
So if I were to type, Hello, There were ^&^ transactions that failed yesterday. and hit a command button used for "Send", it would send an email to the each email address listed in Column B and replace ^&^ with the value in Column C to each individual email address (each row).
Below is the VBA code as an example. There are a lot of other declared variables that I did not mention of course to keep this inquiry as short as possible.
Dim Signature As String, EmailSensitivity As String, EmailImportance As String
Dim Greeting As String, Punctuation As String, Security As String
Sub SendButton1_Click()
If SubjectText = vbNullString Then
If EmailBody1 = vbNullString Then
MsgBox "Form Incomplete:" & vbCrLf & vbCrLf & _
"No Subject or Email Text.", vbOKOnly
Exit Sub
End If
End If
If SubjectText = vbNullString Then
MsgBox "Form Incomplete:" & vbCrLf & vbCrLf & _
"Please enter Subject.", vbOKOnly
Exit Sub
End If
If EmailBody1 = vbNullString Then
MsgBox "Form Incomplete:" & vbCrLf & vbCrLf & _
"Please enter Email Text."
Exit Sub
End If
If SignatureText1 = vbNullString Then
Continue = MsgBox("Your email contains no signature." & vbCrLf & vbCrLf & _
"Are you sure you wish to proceed?", vbYesNo)
If Continue = vbNo Then
Exit Sub
End If
End If
Dim OutApp As Object, OutMail As Object
Dim r As Integer
Application.ScreenUpdating = False
For r = 2 To 501
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(olMailItem)
On Error Resume Next
With OutMail
.Subject = Security & SubjectText.Value
.Body = EmailBody1.Value & vbCrLf & vbCrLf & _
SignatureText1.Value
.To = Cells(r, 2)
.Attachements.Add AttachmentText1.Value
.Importance = EmailImportance
.Sensitivity = EmailSensitivity
.Send
End With
Next r
Set OutApp = Nothing
Application.ScreenUpdating = True
Sheet1.Range("A2:B501").Clear
Continue = MsgBox("You have successfully generated a mass email!" & vbCrLf & vbCrLf & _
"Would you like to generate another email?", vbYesNo)
If Continue = vbNo Then
Application.Quit
End If
End Sub
I am still an amateur, so I'm working on cleaning a lot of unnecessary code, but this inquiry is mainly on replacing the special character with the value listed in each row.
This is my first time actually posting an inquiry on a forum, so please let me know if I am not following the correct procedure as your help is much appreciated.
It might be as simple as this, using the Replace function:
...
With OutMail
.Subject = Security & SubjectText.Value
.Body = Replace(EmailBody1.Value,"^&^",Cells(r, 3)) & _
vbCrLf & vbCrLf & SignatureText1.Value
...
Unrelated to this, but importat: On Error Resume Next means the sending (and any operation after that) will silently fail. This will make future debugging more difficult, frustrating and expensive. You should at least log relevant details about what error occured, and for what row in the sheet. And be sure to re-enable error-checking with on error goto 0 or similar after the part of your program that might fail unexpectedly.

to Sending Email from an ASP classic Page with credentials

I need to send users credentials by email to the users of my app, that is build in asp
classic, this is my issue, from a email account, sent information to an user, but
doesn´t send username and pass from that user, my code is this, how can manage the
user/password? what the best way to do it? thanks in advance.
t1 = time()
estado=""
email="soporte.web#ipsos.com"
mail_from = "Soporte <soporte.web#myenterprise.com>"
mail_destino = "Soporte Web Ipsos" & " <" & email &">"
mail_asunto = "Acceso BCI Satisfaccion " & user
ruta=request.ServerVariables("APPL_PHYSICAL_PATH")
on error resume next
mail_cc=""
Dim myMail
Set myMail = CreateObject("CDONTS.NewMail")
myMail.MailFormat = 0 '0 (Mime format), 1 (default Plain Text format)'
myMail.BodyFormat = 0 '0 html, 1 texto'
myMail.Importance = 1 '0 Low, 1 Normal, 2 High '
myMail.From = mail_from
myMail.To = mail_destino
myMail.Cc = mail_cc
'myMail.Cco = mail_cco'
myMail.Subject = mail_asunto
myMail.Body = texto_email
'myMail.AttachFile ruta&"Carta2006.pdf"'
myMail.Send
Set myMail = Nothing
If err.num <> 0 Then
Response.Write nombre & " / " & email & " / " & "CDONTS Error: " & err.num & " - " &
err.description
estado="no"
End If
end sub
In classic ASP there is no standard way (that I can remember) to deal with username/password, other than a using login page for authentication and session variables for maintaining state.
If you go to the code of the login page in your application and follow the logic you should see the login happen (where username and password are checked). You can then pop those values into a session variable (if this isn't done already) and pull them out later to send in the email.
As an aside, sending a user their username and password in a plain text email is generally discouraged as the email can be read in transit = an opportunity for hackers. But that's up to you...

ASP return OUTPUT value from sproc

How do I return a value from the sproc and assigned it to a variable so that it can be used on the ASP page?
The stored procedure that returns the value is called sp_Auction_PaymentEwayXMLReceive.
The output variable is called ReturnedMsg.
My current code is:
Dim Connection
Dim sSQL, sConnString
sConnString="DRIVER={SQL Server};SERVER=XXXX;UID=XXXX; PWD=XXXX;DATABASE=XXXX;"
sSQL = "sp_Auction_PaymentEwayXMLReceive '"&eWay.ResultEwayTrxnStatus&"','"&eWay.ResultEwayTrxnNumber&"','"&eWay.ResultEwayTrxnReference&"','"&eWay.ResultEwayTrxnOption1&"','"&eWay.ResultEwayTrxnOption2&"','"&eWay.ResultEwayTrxnOption3&"','"&eWay.ResultEwayAuthCode&"','"&eWay.ResultEwayReturnAmount&"','"&eWay.ResultEwayTrxnError&"' "
Set sConnection = Server.CreateObject("ADODB.Connection")
Set connection = Server.CreateObject("ADODB.Connection")
connection.Open(sConnString)
connection.execute(sSQL)
--EDIT--
#Andomar
Re Response 1: I have also tried this but I get a 500 error.
'set up output parameter
dim outputParameter
set outputParameter = _
cmd.CreateParameter("ReturnedMsg",adVarChar, _
adParamOutput,40)
'open conn
connection.Open(sConnString)
'append OUTPUT
cmd.Parameters.Append outputParameter
'exec sql
connection.execute(sSQL)
-R
After you create the connection, add an output parameter:
dim outputParameter
set outputParameter = _
cmd.CreateParameter("OutputParameterName",adVarChar, _
adParamOutput,40)
cmd.Parameters.Append outputParameter
After you run the SP, you can use the values like:
Response.Write("<TD>" & _
cmd.Parameters("OutputParameterName").Value & "</TD>")