WebClient encoding problems is vb.net - vb.net

In my vb.net application I am interacting with a webservice written by another group. This interaction involved verifying an account number. The way the other group wrote their webservice is I am supposed to hit a specific url, retrieve a sessionid number and then use that number for subsequent requests. The problem I am having is that when I pass the sessionid it needs to be contained in { } brackets. for example: "http://server/acctverify/Verification.groovy;jsessionid=${123456789}"
The problem lies in when I pass the above URL it gets encoded to something like this:
http://server/acctverify/Verification.groovy;jsessionid=$%7B123456789%7D
with the {}'s replaced.
I don't understand why this is happening nor how to fix it.
Code I am running:
Dim client As WebClient = New WebClient
Dim Sessionuri As Uri = New Uri(VerifyInit)
Dim sessionID As String = client.DownloadString(Sessionuri)
Dim FinalUri As Uri = New Uri(VerifyPost & "{" & sessionID & "}?acctnumber=")
Dim FinalResults As String = client.DownloadString(FinalUri)
MessageBox.Show(FinalResults)
Thanks in advance for any help.

There is a deprecated constructor for the Uri class which will prevent URIs from being encoded when the dontEscape parameter of the constructor is True.
Like this:
Dim client As WebClient = New WebClient
Dim Sessionuri As Uri = New Uri(VerifyInit)
Dim sessionID As String = client.DownloadString(Sessionuri)
Dim FinalUri As Uri = New Uri(VerifyPost & "{" & sessionID & "}?acctnumber=", true)
Dim FinalResults As String = client.DownloadString(FinalUri)
MessageBox.Show(FinalResults)
This constructor is deprecated for good reason: the URI you're trying to create is not a legal URI. The { and } characters must be encoded. But if you're using a non-compliant server that only accepts unencoded characters, the constructor above should work.

Related

Docusing JWT Access Token Request in vb.net

I want to get JWT Access token for Docusing, i tried use following code to get access token ,after that i pass access token to create envelope, i get an error
"Error calling CreateEnvelope: {
"errorCode": "AUTHORIZATION_INVALID_TOKEN",
"message": "The access token provided is expired, revoked or malformed."
}"
Dim PrivateKey As String = "MIIEowIBAAKCAQEAjtTe7UUP/CBI9s...BLABLABLA...JfwZ2hHqFPXA9ecbhc0".Replace(vbLf, "").Replace(vbCr, "")
Dim ar1 As JObject = New JObject()
ar1.Add("typ", "JWT")
ar1.Add("alg", "RS256")
Dim header As String = Base64UrlEncoder.Encode(ar1.ToString)
Dim ar2 As JObject = New JObject()
ar2.Add("iss", "INTEGRATION_ID")
ar2.Add("sub", "GUID_VERSION_OF_USER_ID")
ar2.Add("iat", DateDiff(DateInterval.Second, New Date(1970, 1, 1), Now().ToUniversalTime))
ar2.Add("exp", DateDiff(DateInterval.Second, New Date(1970, 1, 1), DateAdd(DateInterval.Hour, 1,Now().ToUniversalTime)))
ar2.Add("aud", "account-d.docusign.com")
ar2.Add("scope", "signature")
Dim body As String = Base64UrlEncoder.Encode(ar2.ToString)
Dim stringToSign As String = header & "." & body
Dim bytesToSign() As Byte = Encoding.UTF8.GetBytes(stringToSign)
Dim keyBytes() As Byte = Convert.FromBase64String(PrivateKey)
Dim privKeyObj = Asn1Object.FromByteArray(keyBytes)
Dim privStruct = RsaPrivateKeyStructure.GetInstance(privKeyObj)
Dim sig As ISigner = SignerUtilities.GetSigner("SHA256withRSA")
sig.Init(True, New RsaKeyParameters(True, privStruct.Modulus, privStruct.PrivateExponent))
sig.BlockUpdate(bytesToSign, 0, bytesToSign.Length)
Dim signature() As Byte = sig.GenerateSignature()
Dim sign As String = Base64UrlEncoder.Encode(signature)
Return header & "." & body & "." & sign
I take above code from this link DocuSign JWT Access Token Request, in that user mention working code ,Pls advise me what i make mistakes,
Note : I am get access token and immediately pass that token to create envelope. "iss" is my integration key and "sub" is my userid and Private keyi generate from RSA key pair form on of the my app which created in Apps and Integration Keys
i am use docusing 3.0.0 dll which support .net framework 4.6.1
Regards,
Aravind
If you are using the DocuSign dll (version 3.0.0 is pretty old, I suggest you upgrade BTW) you don't need all this code.
Instead you can do this:
(note that I assume you have a configuration file with the information, you will want to update this code to include the ClientId/IK, UserId, AuthServer and RSA Key location).
Public Sub UpdateUserFromJWT()
Me._authToken = _apiClient.RequestJWTUserToken(Me._configuration("DocuSignJWT:ClientId"), Me._configuration("DocuSignJWT:ImpersonatedUserId"), Me._configuration("DocuSignJWT:AuthServer"), DSHelper.ReadFileContent(DSHelper.PrepareFullPrivateKeyFilePath(Me._configuration("DocuSignJWT:PrivateKeyFile"))), 1)
_account = GetAccountInfo(_authToken)
Me.User = New User With {
.Name = _account.AccountName,
.AccessToken = _authToken.access_token,
.ExpireIn = DateTime.Now.AddSeconds(_authToken.expires_in.Value),
.AccountId = _account.AccountId
}
Me.Session = New Session With {
.AccountId = _account.AccountId,
.AccountName = _account.AccountName,
.BasePath = _account.BaseUri
}
End Sub

How to convert \ using newtonsoft.json.linq.serializeobject in vb.net httprequest?

I have a JSON object created using Newtonsoft JObject but I get a bad request error when I try to submit it if any of the properties have spaces, slashes, etc.
updatestring = "date=2/14/2019"
Dim jobjattr As New Newtonsoft.Json.Linq.JObject(
New Newtonsoft.Json.Linq.JProperty("description", "test"),
New Newtonsoft.Json.Linq.JProperty("source", updatestring)
)
Dim jobjdat As New Newtonsoft.Json.Linq.JObject(
New Newtonsoft.Json.Linq.JProperty("type", "synch_log"),
New Newtonsoft.Json.Linq.JProperty("id", "6278042e-ed64-0418-a651-5c574dc4f12b"),
New Newtonsoft.Json.Linq.JProperty("attributes", jobjattr)
)
Dim jobj As New Newtonsoft.Json.Linq.JObject(New Newtonsoft.Json.Linq.JProperty("data", jobjdat))
Dim jsonserializersettings As New Newtonsoft.Json.JsonSerializerSettings
jsonserializersettings.StringEscapeHandling = Newtonsoft.Json.StringEscapeHandling.EscapeNonAscii
Dim stringReq = Newtonsoft.Json.JsonConvert.SerializeObject(jobj, jsonserializersettings)
Dim byteData As Byte() = System.Text.Encoding.UTF8.GetBytes(stringReq)
httprequest.ContentLength = byteData.Length
Dim postreqstream As System.IO.Stream = .GetRequestStream()
postreqstream.Write(byteData, 0, byteData.Length)
postreqstream.Close()
incoming jobj = {"data":{"type":"synch_log","id":"6278042e-ed64-0418-a651-5c574dc4f12b","attributes":{"description":"test","source":"date=2/14/2019"}}}
after serialzation byteData still = {"data":{"type":"synch_log","id":"6278042e-ed64-0418-a651-5c574dc4f12b","attributes":{"description":"test","source":"date=2/14/2019"}}}
I would expect the / to be escaped.
any text string works fine
I have also tried jsonserializer settings as Default and EscapeHtml but with the same result.
Other characters cause the same eror. "datetoday" posts correctly but "date=today" and "date today" result in a 400 bad request error
The closest answer I have found is that maybe the object is being double escaped but I can't see how that would be.
Thank you everyone. Brian, you led me in the right direction. I failed to mention that it is an API call to SuiteCRM but your question got me thinking to look on the server side and it turns out there is an unresolved bug with the V8 API. I just assumed it was my code.
github bug report

Make checking a string not case sensitive

I'm making a program which a user enters an item in a text box and the program will check if the item is in the string. Here is my current code:
Try
Dim Request As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create("https://www.dropbox.com/s/2l37j6v0ofsenus/Foods.txt?dl=1")
Dim Response As System.Net.HttpWebResponse = Request.GetResponse()
Dim sr As System.IO.StreamReader = New System.IO.StreamReader(Response.GetResponseStream)
Dim Foods As String = sr.ReadToEnd()
If Foods.Contains(TXTItem1.Text) Then
Dim Substring As String = Foods.Split(TXTItem1.Text)(1)
Dim SubString1 As String = Substring.Split("-")(1)
Dim SPValue As String = SubString1.Split(vbNewLine)(0)
MsgBox("That item is worth " + SPValue + " SmartPoints!", info)
Else
MsgBox("Item is not found in our list!", critical)
End If
Catch ex As Exception
MsgBox("Error")
End Try
I want to make it where when it checks the string, it is not case sensitive. So if a user enters "eggs" and the string contains "Eggs", it will do the function still even tho its lower-case. How can I do this? Thanks!
If you convert the string you're testing to lowercase, and also the string you are testing against to lowercase, then case is no longer a consideration!
There are functions that can do this for you, but the logic behind them is always the same ... Caseless comparison requires both pieces of data to be converted to either all lowercase (or all uppercase), before the comparison is undertaken. I
The linked question that's referred to by #jacob-h in the comment above already has answers to your question, but I prefer an extension method in this case.
Here's an extension method version that I've been using for a while. Add a new Module to your project (or use an existing one if you find it appropriate), and add this extension method to it:
<Runtime.CompilerServices.Extension>
Public Function ContainsIgnoreCase(ByVal s As String, ByVal value As String)
Return s.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0
End Function
Then you can use something like this:
If Foods.ContainsIgnoreCase(TXTItem1.Text) Then
' Do your thing.
End If

Visual Basic set User Agent with ReadXml

I'm trying to set the user agent for a request with XmlRead. I googled a lot about this and couldn't find the answer. Here is my chunk of code:
Dim RssData As DataSet
Dim Title As String
Dim Url As String
Dim Stream As String
Dim buffer As Integer
RssData = New DataSet()
RssData.ReadXml("http://localhost/user_agent.php")
buffer = 0
For Each RssRow As DataRow In RssData.Tables("entry").Rows
Title = Microsoft.VisualBasic.Left(RssRow.Item("title").ToString, 30)
Stream += Title & vbCrLf
Next
LinkLabel3.Text = Stream
For Each RssRow As DataRow In RssData.Tables("entry").Rows
Title = Microsoft.VisualBasic.Left(RssRow.Item("title").ToString, 30)
Url = RssRow.Item("url").ToString
LinkLabel3.Links.Add(buffer, Title.Length, Url)
buffer = buffer + Title.Length + 2
Next
The part of the code that actually performs the web request is buried pretty deep so you'd have to inherit a bunch of code to do what you asked for. Instead, let me suggest a different path, download the XML on your own with code that's easy to set that header, and then load that into the dataset. The WebClient class lets you set arbitrary headers and has a simple DownloadString method. Once you've got that you can wrap it in a MemoryStream and pass that into ReadXml(). (I couldn't find a way to read the XML as a string, that's why I was forced to read it as Stream.)
''//Will hold our downloaded XML
Dim MyXml As String
''//Create a webclient to download our XML
Using WC As New System.Net.WebClient()
''//Manually set the user agent header
WC.Headers.Add("user-agent", "your user agent here")
''//Download the XML
MyXml = WC.DownloadString("http://localhost/user_agent.php")
End Using
''//Create our dataset object
Dim RssData As New DataSet()
''//There is no direct method to load XML as a string (at least that I could find) so we will
''// convert it to a byte array and load it into a memory stream
Dim Bytes As Byte() = System.Text.Encoding.UTF8.GetBytes(MyXml)
Using MS As New System.IO.MemoryStream(Bytes)
''//Load the stream into the reader
RssData.ReadXml(MS)
End Using
''//Your code continues normally here

How can I get the URL and Querystring? vb.net

I am refactoring some legacy code. The app was not using querystrings. The previous developer was hard coding some variables that the app uses in other places.
Like this using VB.NET
so.Cpage = "ContractChange.aspx"
My question is can I programatically set this value and include the current querystring?
I want so.Cpage to be something like ContractChange.aspx?d=1&b=2
Can I do this with the request object or something? Note, I don't need the domain.
To get the current query string you would simply do something like the following:
Dim query as String = Request.QueryString("d")
This will assign the value of the "d" querystring to the string variable "query". Note that all query string values are strings, so if you're passing numbers around, you'll need to "cast" or convert those string values to numerics (be careful of exceptions when casting, though). For example:
Dim query as String = Request.QueryString("d")
Dim iquery as Integer = CType(query, Integer)
The QueryString property of the Request object is a collection of name/value key pairs. Specifically, it's of type System.Collections.Specialized.NameValueCollection, and you can iterate through each of the name/value pairs as so:
Dim coll As System.Collections.Specialized.NameValueCollection = Request.QueryString
Dim value As String
For Each key As String In coll.AllKeys
value = coll(key)
Next
Using either of these mechanisms (or something very similar) should enable you to construct a string variable which contains the full url (page and querystrings) that you wish to navigate to.
Try this:
so.Cpage = "ContractChange.aspx?" & Request.RawUrl.Split("?")(1)
In VB.Net you can do it with the following.
Dim id As String = Request.Params("RequestId")
If you want to process this in as an integer, you can do the following:
Dim id As Integer
If Integer.TryParse(Request.Params("RequestId"), id) Then
DoProcessingStuff()
End If
try this
Dim name As String = System.IO.Path.GetFileName(Request.ServerVariables("SCRIPT_NAME"))
Dim qrystring As String = Request.ServerVariables("QUERY_STRING")
Dim fullname As String = name & "/" & qrystring
Not sure about the syntax in VB.NET but in C# you would just need to do
StringId = Request.QueryString.Get("d");
Hope this helps.