Deserialize Json for multi-language support - vb.net

I have tried de-serializing with suggested code in this forum.
I use a Google Translate API. It returns a JSON string.
I use Newtonsoft.Json to de-serialize.
My code does not work for foreign language translations, where the string to deserialise is more than one byte.
The code is shown below:
Public Function getGoogleTranslate(myIncomingText As String) As String
Dim myUrlString As String
Dim myLanguageFrom As String
Dim myLanguageTo as string
Dim myTextFrom As String
Dim myNewString As String
myLanguageFrom = "en"
myLanguageTo = "fr"
myTextFrom = myIncomingText
myUrlString = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl="
myUrlString &= myLanguageTo
myUrlString &= "&hl="
myUrlString &= myLanguageFrom
myUrlString &= "&dt=t&dt=bd&dj=1&source=icon&q="
myUrlString &= myIncomingText
Dim myWebClient As New System.Net.WebClient
Dim myDowloadString As String = myWebClient.DownloadString(myUrlString)
Dim myJsonFile As Newtonsoft.Json.Linq.JObject = Newtonsoft.Json.Linq.JObject.Parse(myDowloadString)
myNewString = myJsonFile.SelectToken("sentences[0]").SelectToken("trans")
Return myNewString
End Function
Everything works. I call the API using the URL specified as "MyURLString".
The returned line is returned into the string myDownloadString.
Investigation of this string is that the translated text is returned correctly.
After the resulting string is parsed, only characters in the ASCII range are decoded as expected, not characters used in other languages.
It could be the myNewString variable, which is declared as a standard string.
However, if I cut and paste the translated text into a TextBox on the web page, the special characters are accepted and stored in a SQL table correctly.
It gets even more complex when translation to "ru" (Russian) or "zh" (simplified Chinese).
I have never worked with a different language character set. So I am flying blind, with only this forum for help.

The data you're downloading is UTF8 encoded.
You can decode it using Encoding.UTF8.GetString(), downloading the results as a byte array, using the DownloadData() method instead of DonloadString().
' [...]
Dim data As Byte()
Dim jsonResult as String = String.Empty
Using client As New WebClient()
data = client.DownloadData(myUrlString)
jsonResult = Encoding.UTF8.GetString(data)
End Using
' Deserialize the jsonResult object
Unfortunately, WebClient doesn't care at all about the encoding of the incoming string, it always uses the Local encoding, unless otherwise specified, setting its Encoding Property. Or using other means, as shown here. You need to know what the encoding is beforehand, though. Or you could read the Encoding from the underlying WebResponse object.
Option 2: use HttpClient instead of WebClient. This class handles the encoding specified by the remote source:
' Declare a static (`Shared`) HttpClient object as a Field
Private Shared client As New HttpClient()
' Make an async method:
Private async Function GetGoogleTranslation(textToTranslate As String) As String
' Declare your local variables
' [...]
Dim jsonResult as String = String.Empty
Using response = Await client.GetAsync(myUrlString)
If response.IsSuccessStatusCode Then
jsonResult = Await response.Content.ReadAsStringAsync()
End If
End Using
' Deserialize and get the results you need
Dim result = [...] ' Deserialize the result
Return result
End Function

I have managed to crack this. It was not a JSON problem after all. The problem was in the programmer. I added one line of code to my solution:
myWebClient.Encoding = System.Text.UTF8Encoding.UTF8
NewtonSoft does handle the parse correctly, even if the incoming string is in UTF8.
Thanks for your answer Jimi.

The working code to call the Google translate API from VB.NET. Note: I have tested this with French and German translations but not with Chinese yet.
Public Function getGoogleTranslate(myIncomingText As String) As String
Dim myUrlString As String
Dim myLanguageFrom As String
Dim myLanguageTo as string
Dim myTextFrom As String
Dim myNewString As String
myLanguageFrom = "en"
myLanguageTo = "fr"
myTextFrom = myIncomingText
myUrlString = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl="
myUrlString &= myLanguageTo
myUrlString &= "&hl="
myUrlString &= myLanguageFrom
myUrlString &= "&dt=t&dt=bd&dj=1&source=icon&q="
myUrlString &= myIncomingText
Dim myWebClient As New System.Net.WebClient
myWebClient.Encoding = System.Text.UTF8Encoding.UTF8
Dim myDowloadString As String = myWebClient.DownloadString(myUrlString)
Dim myJsonFile As Newtonsoft.Json.Linq.JObject = Newtonsoft.Json.Linq.JObject.Parse(myDowloadString)
myNewString = myJsonFile.SelectToken("sentences[0]").SelectToken("trans")
Return myNewString
End Function

Related

How to convert encoding of FTP Getlisting array of strings?

I am using the following vb code to get the list of files in a ftp directory and populate a database table with it to be used in another integration process. Please forgive my bad bad programming skills (I am not a vb.net developer).
Public Sub Main()
Dim StrFolderArrary As String() = Nothing
Dim StrFileArray As String() = Nothing
Dim fileName As String
Dim RemotePath As String
RemotePath = Dts.Variables("User::FTPFullPath").Value.ToString()
Dim ADODBConnection As SqlClient.SqlConnection
ADODBConnection = DirectCast(Dts.Connections("DB_Connection").AcquireConnection(Dts.Transaction), SqlClient.SqlConnection)
Dim cm As ConnectionManager = Dts.Connections("FTP_Connection") 'FTP connection manager name
Dim ftp As FtpClientConnection = New FtpClientConnection(cm.AcquireConnection(Nothing))
ftp.Connect() 'Connecting to FTP Server
ftp.SetWorkingDirectory(RemotePath) 'Provide the Directory on which you are working on FTP Server
ftp.GetListing(StrFolderArrary, StrFileArray) 'Get all the files and Folders List
'If there is no file in the folder, strFile Arry will contain nothing, so close the connection.
If StrFileArray Is Nothing Then
ftp.Close()
'If Files are there, Loop through the StrFileArray arrary and insert into table
Else
For Each fileName In StrFileArray
'MessageBox.Show(fileName)
Dim SQLCommandText As String
SQLCommandText = "INSERT INTO dbo._FTPFileList ([DirName],[FileName]) VALUES (N'" + RemotePath + "', N'" + fileName + "')"
'MessageBox.Show(SQLCommandText)
Dim cmdDatabase As SqlCommand = New SqlCommand(SQLCommandText, ADODBConnection)
cmdDatabase.ExecuteNonQuery()
Next
ftp.Close()
End If
' Add your code here
'
Dts.TaskResult = ScriptResults.Success
End Sub
It works fine and I get the results in the database table. The problem is that the encoding of the strings coming from FTP makes the file names with accentuation to be written incorrectly as shown in the example below.
database table
The correct file name is Razão and I know that the db collation is correct since it can be written like this.
So I tried to convert the strings using this code for each file name in the string array but without any success.
For Each fileName In StrFileArray
Dim utf8 As UTF8Encoding = New UTF8Encoding(True, True)
Dim bytes As Byte() = New Byte(utf8.GetByteCount(fileName) + utf8.GetPreamble().Length - 1) {}
Array.Copy(utf8.GetPreamble(), bytes, utf8.GetPreamble().Length)
utf8.GetBytes(fileName, 0, fileName.Length, bytes, utf8.GetPreamble().Length)
Dim fileName2 As String = utf8.GetString(bytes, 0, bytes.Length)
I believe it is coming with different encoding from the FTP side so I would like to know how to convert the strings during the GetListing method.
Or do you have any ideas how to deal with this?
Thanks in advance.
edit:
I also tried the following code without success.
Dim utf8 As Encoding = Encoding.UTF8
Dim w1252 As Encoding = Encoding.GetEncoding(1252)
Dim w1252Bytes As Byte() = w1252.GetBytes(fileName)
Dim utf8Bytes As Byte() = Encoding.Convert(w1252, utf8, w1252Bytes)
Dim utf8Chars As Char() = New Char(utf8.GetCharCount(utf8Bytes, 0, utf8Bytes.Length) - 1) {}
utf8.GetChars(utf8Bytes, 0, utf8Bytes.Length, utf8Chars, 0)
Dim fileName2 As String = New String(utf8Chars)

How to return a string from a text file with condition met?

Public Sub openDB()
Dim Lines As New List(Of String)
Try
' Open the file using a stream reader.
Using sr As New StreamReader("Config.txt")
Dim line As String
' Read the stream to a string and write the string to the console.
line = sr.ReadLine()
Do Until String.IsNullOrEmpty(line)
Lines.Add(line)
line = sr.ReadLine
Loop
End Using
Catch e As Exception
Console.WriteLine("The file could not be read:")
Console.WriteLine(e.Message)
End Try
Dim dbname As String = g_DatabaseName
Dim server As String = Lines.Where(Function(str) str.Contains("server =")).ToString
Dim user As String = ""
Dim password As String = ""
conn = New MySqlConnection
conn.ConnectionString = String.Format("server={0}; user id={1}; password={2}; database={3}; pooling=false; Convert Zero Datetime=True", server, user, password, dbname)
conn.Open()
End Sub
Im try to return some string from a text file, so I use StreamReader to read the file and store them into a list. Now I try to declare a variable to get "localhost" from list of string, but the code below is not work for me.
Dim server As String = Lines.Where(Function(str) str.Contains("server
=")).ToString
Enumerable.Where does not return a single string but possibly multiple, using ToString gives you not the first matching line but just the name of the type which is System.Linq.Enumerable+WhereArrayIterator1[System.String].
Either declare it as IEnumerable(Of String) or use First/ FirstOrDefault to get the first line that matches the condition:
Dim serverLine As String = Lines
.Where(Function(str) str.Contains("server ="))
.FirstOrDefault()
You can also use the overload of FirstOrDefault(Nothing if there was no such line):
Dim serverLine As String = Lines.FirstOrDefault(Function(str) str.Contains("server ="))
To extract Localhost:
Dim server As String = serverLine.Substring(serverLine.IndexOf("server =") + "server =".Length).Trim(""""c, " "c)

Issue with StreamReader

I am writing code where I am trying to grab the HTML from a DNS report online (http://viewdns.info/dnsreport/?domain=google.com), but I am having some issues. The one line of the HTML file (Line 231) that I actually need is cutting itself off after around 680 characters. All of the lines after the important one are reading correctly, however. The code for grabbing the HTML is shown below, and I have tried it in two separate ways.
This is the first way I tried:
Public Function getWebResourceData(ByVal strURL As String) As String
Dim webClient As New System.Net.WebClient
Dim result As String = webClient.DownloadString("http://viewdns.info/dnsreport/?" & TextBox1.Text)
return result
End Function
And this is the second:
Public Function getWebResourceData(ByVal strURL As String) As String
Dim rt As String = ""
Dim wRequest As WebRequest
Dim wResponse As WebResponse
Dim SR As StreamReader
wRequest = WebRequest.Create(strURL)
wResponse = wRequest.GetResponse
SR = New StreamReader(wResponse.GetResponseStream)
rt = SR.ReadToEnd
SR.Close()
return rt
End Function
Im really not sure what else could be wrong at this point. I have also tried saving the result to a text file to see if that was the issue, but that was incorrect as well. I have looked into the hex codes for the area where the string is stopping, but there isn't anything out of the ordinary. The split occurs between the back to back alligator brackets (shown as parentheses) here: (/tr)(tr)
But there are numerous sets of these tags throughout the HTML that there are no issues with.
Both of your functions don't return what they have read. I have tested the second one and it works correctly.
Sub Main
Dim ret = getWebResourceData("http://viewdns.info/dnsreport/?domain=google.com")
Console.WriteLine(ret.Length)
' Output = 21605
End Sub
Public Function getWebResourceData(ByVal strURL As String) As String
Dim rt As String = ""
Dim wRequest As WebRequest
Dim wResponse As WebResponse
Dim SR As StreamReader
wRequest = WebRequest.Create(strURL)
wResponse = wRequest.GetResponse
SR = New StreamReader(wResponse.GetResponseStream)
rt = SR.ReadToEnd
SR.Close()
return rt
End Function

Suggest correction in code to render report

I was suggested the following code to programmatically render SSRS report in PDF format.
I tried it but it is not working.
Can any body suggest what might be required?
Thanks
Dim format As String = "PDF"
Dim fileName As String = "C:\Output.pdf"
Dim reportPath As String = "/[Report Folder]/Invoice"
' Prepare Render arguments
Dim historyID As String = Nothing
Dim deviceInfo As String = Nothing
Dim extension As String = Nothing
Dim encoding As String
Dim mimeType As String = "application/pdf"
Dim warnings() As Microsoft.Reporting.WinForms.Warning = Nothing
Dim streamIDs() As String = Nothing
Dim results() As Byte
ReportViewer1.LocalReport.Render(format, deviceInfo, mimeType, encoding, fileName, streamIDs, warnings)
' Open a file stream and write out the report
Dim stream As FileStream = File.OpenWrite(fileName)
stream.Write(results, 0, results.Length)
stream.Close()
It doesn't work because you never assign anything to the results variable so the FileStream will never get anything written to it. You need to assign the result of the Render method to results:
results = ReportViewer1.LocalReport.Render(format, deviceInfo, mimeType, encoding, fileName, streamIDs, warnings)

Issue in splitting an array of strings

I'm using webrequests to retrieve data in a .txt file that's on my dropbox using this "format".
SomeStuff
AnotherStuff
StillAnother
And i'm using this code to retrieve each line and read it:
Private Sub DataCheck()
Dim datarequest As HttpWebRequest = CType(HttpWebRequest.Create("https://dl.dropboxusercontent.com.txt"), HttpWebRequest)
Dim dataresponse As HttpWebResponse = CType(datarequest.GetResponse(), HttpWebResponse)
Dim sr2 As System.IO.StreamReader = New System.IO.StreamReader(dataresponse.GetResponseStream())
Dim datastring() As String = sr2.ReadToEnd().Split(CChar(Environment.NewLine))
If datastring(datastring.Length - 1) <> String.Empty Then
For Each individualdata In datastring
MessageBox.Show(individualdata)
Console.WriteLine(individualdata)
Next
End If
End Sub
The problem is, the output is this:
It always adds a line break (equal to " " as i see as first character on each but the first line string) after the first line like:
http://img203.imageshack.us/img203/1296/gejb.png
Why this happens? I tried also replacing the Environment.Newline with nothing like this:
Dim newstring as String = individualdata.Replace(Environment.Newline, String.Empty)
But the result was the same... what's the problem here? I tried with multiple newline strings and consts like vbnewline, all had the same result, any ideas?
You are not splitting by NewLine since you are cutting off Environment.NewLine which is a string with CChar. You just have to use the overload of String.Split that takes a String() and a StringSplitOption:
So instead of
Dim text = sr2.ReadToEnd()
Dim datastring() As String = text.Split(CChar(Environment.NewLine))
this
Dim datastring() As String = text.Split({Environment.NewLine}, StringSplitOptions.None)
I suspect that your file contains a mix of NewLine+CarriageReturn (vbCrLf) and a simple NewLine (vbLf).
If this is the case then you could create an array of the possible separators
Dim seps(2) as Char
seps(0) = CChar(vbLf)
seps(1) = CChar(vbCr)
Dim datastring() As String = sr2.ReadToEnd().Split(seps, StringSplitOptions.RemoveEmptyEntries)
The StringSplitOptions.RemoveEmptyEntries is required because a vbCrLf creates an empty string between the two separators