GetResponse not a member of WebRequest in UWP - vb.net

I wrote a VB program to access information from the Web.
It works but when trying to do the same thing in UWP (Universal Windows) …
I get the following message:
"'GetResponse' is not a member of 'WebRequest'"
Here is the code I am using less the website info. How can this code be used in the Universal Windows Platform.
Imports System
Imports System.IO
Imports System.Net
Module Code
Sub SendWebRequest()
Dim MyWebRequest As WebRequest
Dim MyWebResponse As WebResponse
Dim SR As StreamReader
Dim ReadString As String
Dim MyCache As New CredentialCache()
Dim MyCredential As NetworkCredential = MyCache.GetCredential(New Uri("http://xxxxxx.com:xxxx"), "Basic")
If MyCredential Is Nothing Then
MyCache.Add(New Uri("http://http://xxxxxx.com:xxxx"), "Basic", New NetworkCredential("UserName", "UsePassWord"))
End If
MyWebRequest = WebRequest.Create("http://http://xxxxxx.com:xxxx/xxxx")
MyWebRequest.Credentials = myCache
MyWebResponse = MyWebRequest.GetResponse()
SR = New StreamReader(MyWebResponse.GetResponseStream)
Do
ReadString = SR.ReadLine
If InStr(ReadString, "Listen to the pronunciation of") Then
'Do Something
Exit Do
End If
Loop Until SR.EndOfStream
MyWebResponse.Close()
End Sub
End Module
I updated using adding Async and Await . . .
Run time issue at MyWebresponse = Await MyWebRequest.GetResponseAsync()
Exception User-Unandled: System.PlatformNotSupportedException: 'The value 'System.Net.CredentialCache' is not supported for property 'Credentials'.'
Async Sub SendWebRequest()
Dim MyWebRequest As WebRequest
Dim MyWebResponse As WebResponse
Dim SR As StreamReader
Dim ReadString As String
Dim MyCache As New CredentialCache()
Dim MyCredential As NetworkCredential = MyCache.GetCredential(New Uri("http://xxxxxx.com:xxxx"), "Basic")
If MyCredential Is Nothing Then
MyCache.Add(New Uri("http://http://xxxxxx.com:xxxx"), "Basic", New NetworkCredential("UserName", "UsePassWord"))
End If
MyWebRequest = WebRequest.Create("http://http://xxxxxx.org:xxxx/xxxx")
MyWebRequest.Credentials = myCache
MyWebResponse = Await MyWebRequest.GetResponseAsync()
SR = New StreamReader(MyWebResponse.GetResponseStream)
Do
ReadString = SR.ReadLine
If InStr(ReadString, "Listen to the pronunciation of") Then
'Do Something
Exit Do
End If
Loop Until SR.EndOfStream
MyWebResponse.Close()
End Sub
If someone can see what I am doing wrong above, I'd appreciate it.
In the mean time I'll try HttpClient as suggested by jmcilhinney

In theory, you should be able to change this:
Sub SendWebRequest()
to this
Async Sub SendWebRequest()
and this:
MyWebResponse = MyWebRequest.GetResponse()
to this:
MyWebResponse = Await MyWebRequest.GetResponseAsync()
This thread indicates that that might not work though. It does suggest an HttpClient as an alternative though, which would mean code something like this:
Dim client As New HttpClient
Dim response = Await client.GetAsync(New Uri("URL here"))
If response.IsSuccessStatusCode Then
Dim data = Await response.Content.ReadAsStringAsync()
For Each line In data.Split({vbLf, vbCrLf}, StringSplitOptions.RemoveEmptyEntries)
'Use line here.
Next
End If
Note that I'm not 100% sure whether those 'vb' constants would work in UWP but I used them here for simplicity.

The following does what I need in UWP. Send a Web Request and monitor the return.
...Thanks jmcilhinney for your help
Imports System.Net
Imports System.Net.Http
Imports System.Text
Module Code
Async Sub SendWebRequest()
Dim client As New HttpClient
Dim byteArray = Encoding.ASCII.GetBytes("UserName:PassWord")
client.DefaultRequestHeaders.Authorization = New System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray))
Dim response = Await client.GetAsync(New Uri("http://xxxxx.xxxxxx.org:####/xxxxx"))
If response.IsSuccessStatusCode Then
Dim data = Await response.Content.ReadAsStringAsync()
For Each line In data.Split({vbLf, vbCrLf}, StringSplitOptions.RemoveEmptyEntries)
'Use line here.
Next
End If
End Sub
End Module

Related

400 bad request when querying microsoft graph with http post

I've been doing some testing with Microsoft Graph and I seem to have hit a brick wall; Wondering if anyone can give me a steer in the right direction.
The following code is from my test app (vb)...
Imports System.Net
Imports System.Text
Imports System.IO
Imports Newtonsoft.Json.Linq
Class MainWindow
Public Shared graph_url As String = "https://graph.microsoft.com/v1.0/"
Public Shared br As String = ControlChars.NewLine
Dim myscope As String = "https://graph.microsoft.com/.default"
Dim mysecret As String = "zzx...BX-"
Dim mytenantid As String = "7aa6d...d409199"
Dim myclientid As String = "4e37...5a59"
Dim myuri As String = "https://login.microsoftonline.com/" & mytenantid & "/oauth2/v2.0/token"
Dim mytoken As String = ""
Public Function HTTP_Post(ByVal url As String, ByVal postdata As String)
Try
Dim encoding As New UTF8Encoding
Dim postReq As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
postReq.Headers.Add("Authorization", "Bearer " & mytoken)
postReq.Method = "POST"
postReq.PreAuthenticate = True
Dim postreqstream As Stream = postReq.GetRequestStream()
If Not postdata = Nothing Then
Dim byteData As Byte() = encoding.GetBytes(postdata)
postreqstream.Write(byteData, 0, byteData.Length)
End If
postreqstream.Close()
request_header.Text = postReq.Headers.ToString
Dim postresponse As HttpWebResponse = DirectCast(postReq.GetResponse(), HttpWebResponse)
Dim postreqreader As New StreamReader(postresponse.GetResponseStream())
Dim response As String = postreqreader.ReadToEnd
Return (response)
Catch ex As Exception
user_results.Text = ex.Message.ToString
End Try
End Function
Public Function GetNewToken()
Console.WriteLine(myuri)
Dim post_data As String = "client_id=" & myclientid & "&client_secret=" & mysecret & "&scope=" & myscope & "&grant_type=client_credentials"
Dim token As String = HTTP_Post(myuri, post_data)
get_result.Text = JObject.Parse(token).SelectToken("access_token")
mytoken = JObject.Parse(token).SelectToken("access_token")
End Function
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
GetNewToken()
End Sub
Private Sub usrget_Copy_Click(sender As Object, e As RoutedEventArgs) Handles usrget_Copy.Click
Dim url As String = "https://graph.microsoft.com/v1.0/users/*{myUPN}*"
Dim post_data As String = Nothing
Dim return_data As String = HTTP_Post(url, post_data)
req_url.Text = url
End Sub
End Class
The GetNewToken() function works fine and I retrive a valid token without an issue.
When i try and use that token to query a user, i get 400 Bad request - no additional info as such; just that.
I've examined the headers of my POST request and tried it several different ways, but cannot seem to overcome this; As far as i can tell my request is formatted as specified in the documentation for Microsoft Graph.
Have also googled the hell out of this to see if there was something obvious or simple I have overlooked; I've seen a few posts on this topic where people suggested setting the Authorization header before anything else - I tried that and it made no difference.
A few people also suggected setting the Accept to 'application/json'; I also tried that and it made no difference.
I've outputted some of the details to the gui and grabbed a screenshot so you can see what I'm seeing...
Interestingly, If i try the 'Query users' before i grab a token, I get a 401 unauthorized which would suggest that the request itself is working correctly.
As i mentioned, this is a testing app whilst I get some functionality working (some data obscured for obvious reasons); I'm not concerned about the tidyness of code or anything like that at this point.
If anyone is able to help it would be very much appriciated.
Thanks in advance.

Background Program Not Looping

I have a program that runs in the background looping to check if a page on the site has been changed. It works once and shows the message box but if I change it again it won't do anything.
Imports System.Net
Imports System.String
Imports System.IO
Module Main
Sub Main()
While 1 = 1
Dim client As WebClient = New WebClient()
Dim reply As String = client.DownloadString("http://noahcristinotesting.dx.am/file.txt")
If reply.Contains("MsgBox") Then
Dim Array() As String = reply.Split(":")
MessageBox.Show(Array(2), Array(1))
Dim request As System.Net.FtpWebRequest = DirectCast(System.Net.WebRequest.Create("ftp://noahcristinotesting.dx.am/noahcristinotesting.dx.am/file.txt"), System.Net.FtpWebRequest)
request.Credentials = New System.Net.NetworkCredential("username", "password")
request.Method = System.Net.WebRequestMethods.Ftp.UploadFile
Dim path As String = "C:\test.txt"
Dim createText As String = "completed"
File.WriteAllText(path, createText)
Dim fileftp() As Byte = System.IO.File.ReadAllBytes("C:\test.txt")
Dim strz As System.IO.Stream = request.GetRequestStream()
strz.Write(fileftp, 0, fileftp.Length)
strz.Close()
strz.Dispose()
End If
End While
End Sub
End Module
Not sure at this moment what is causing it to crash when run outside of the IDE, but try trapping exceptions that are being thrown in the loop. I imagine there's an exception happening, cratering your app. The below catch block is by no means production ready, normally you want to catch specific exceptions in order to handle them effectively, but this is a cheap way to see if an exception is being thrown and what it is at runtime.
Sub Main()
Try
While 1 = 1
Dim client As WebClient = New WebClient()
Dim reply As String = client.DownloadString("http://noahcristinotesting.dx.am/file.txt")
If reply.Contains("MsgBox") Then
Dim Array() As String = reply.Split(":")
MessageBox.Show(Array(2), Array(1))
Dim request As System.Net.FtpWebRequest = DirectCast(System.Net.WebRequest.Create("ftp://noahcristinotesting.dx.am/noahcristinotesting.dx.am/file.txt"), System.Net.FtpWebRequest)
request.Credentials = New System.Net.NetworkCredential("username", "password")
request.Method = System.Net.WebRequestMethods.Ftp.UploadFile
Dim path As String = "C:\test.txt"
Dim createText As String = "completed"
File.WriteAllText(path, createText)
Dim fileftp() As Byte = System.IO.File.ReadAllBytes("C:\test.txt")
Dim strz As System.IO.Stream = request.GetRequestStream()
strz.Write(fileftp, 0, fileftp.Length)
strz.Close()
strz.Dispose()
End If
End While
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Alternatively, you could check your event viewer in windows to see if a .net application exception is being logged. Event Viewer > Windows Logs > Application

How to parse Net.WebClient results with VB.net

Using client As New Net.WebClient
Dim reqparm As New Specialized.NameValueCollection
'reqparm.Add("param1", "somevalue")
'reqparm.Add("param2", "othervalue")
Dim responsebytes = client.UploadValues("http://ip2country.sourceforge.net/ip2c.php?format=JSON", "POST", reqparm)
Dim responsebody = (New Text.UTF8Encoding).GetString(responsebytes)
End Using
Results in:
{ip: "184.23.135.130",hostname:
"184-23-135-130.dedicated.static.sonic.net",country_code:
"US",country_name: "United States"}
Looking for any help
I figured it out. I included Json.net references.
Imports Newtonsoft.Json.Linq
Imports System.Net
Using client As New Net.WebClient
Dim reqparm As New Specialized.NameValueCollection
'reqparm.Add("param1", "somevalue")
'reqparm.Add("param2", "othervalue")
Dim responsebytes = client.UploadValues("http://ip2country.sourceforge.net/ip2c.php?format=JSON", "POST", reqparm)
Dim responsebody = (New Text.UTF8Encoding).GetString(responsebytes)
Dim blah As String = client.DownloadString("http://ip2country.sourceforge.net/ip2c.php?format=JSON")
Dim json As JObject = JObject.Parse(responsebody)
Console.WriteLine(json.SelectToken("ip"))
Console.WriteLine(json.SelectToken("hostname"))
Console.WriteLine(json.SelectToken("country_code"))
Console.WriteLine(json.SelectToken("country_name"))
Console.ReadKey()
End Using

Importing Google Drive Quickstart Code to Visual Basic

I am trying to get the Quickstart code for .Net imported to Visual Basic (VB .NET) and I had some errors. I am a newbie to this kind of programming. Would appreciate some pointers, or someone pointing out something that is fundamentally wrong with the code.
Appreciate the help!
The errors that I get when I try to compile the Console App are:
Error 2 Argument not specified for parameter 'arg' of 'Private Shared Function GetAuthorization(arg As Google.Apis.Authentication.OAuth2.DotNetOpenAuth.NativeApplicationClient) As DotNetOpenAuth.OAuth2.IAuthorizationState'. C:\Documents and Settings\Hirak\Local Settings\Application Data\Temporary Projects\Nipod Drive Console\Module1.vb 22 86 Nipod Drive Console
Error 3 'BaseClientService' is ambiguous in the namespace 'Google.Apis.Services'. C:\Documents and Settings\Hirak\Local Settings\Application Data\Temporary Projects\Nipod Drive Console\Module1.vb 23 48 Nipod Drive Console
Imports System
Imports System.Diagnostics
Imports DotNetOpenAuth.OAuth2
Imports Google.Apis.Authentication.OAuth2
Imports Google.Apis.Authentication.OAuth2.DotNetOpenAuth
Imports Google.Apis.Drive.v2
Imports Google.Apis.Drive.v2.Data
Imports Google.Apis.Util
Imports Google.Apis.Services
Namespace GoogleDriveSamples
Class DriveCommandLineSample
Shared Sub Main(ByVal args As String)
Dim CLIENT_ID As [String] = "YOUR_CLIENT_ID"
Dim CLIENT_SECRET As [String] = "YOUR_CLIENT_SECRET"
'' Register the authenticator and create the service
Dim provider = New NativeApplicationClient(GoogleAuthenticationServer.Description, CLIENT_ID, CLIENT_SECRET)
Dim auth = New OAuth2Authenticator(Of NativeApplicationClient)(provider, GetAuthorization)
Dim service = New DriveService(New BaseClientService.Initializer() With { _
.Authenticator = auth _
})
Dim body As New File()
body.Title = "My document"
body.Description = "A test document"
body.MimeType = "text/plain"
Dim byteArray As Byte() = System.IO.File.ReadAllBytes("document.txt")
Dim stream As New System.IO.MemoryStream(byteArray)
Dim request As FilesResource.InsertMediaUpload = service.Files.Insert(body, stream, "text/plain")
request.Upload()
Dim file As File = request.ResponseBody
Console.WriteLine("File id: " + file.Id)
Console.WriteLine("Press Enter to end this process.")
Console.ReadLine()
End Sub
Private Shared Function GetAuthorization(ByVal arg As NativeApplicationClient) As IAuthorizationState
' Get the auth URL:
Dim state As IAuthorizationState = New AuthorizationState( New () {DriveService.Scopes.Drive.GetStringValue()})
state.Callback = New Uri(NativeApplicationClient.OutOfBandCallbackUrl)
Dim authUri As Uri = arg.RequestUserAuthorization(state)
' Request authorization from the user (by opening a browser window):
Process.Start(authUri.ToString())
Console.Write(" Authorization Code: ")
Dim authCode As String = Console.ReadLine()
Console.WriteLine()
' Retrieve the access token by using the authorization code:
Return arg.ProcessUserAuthorization(authCode, state)
End Function
End Class
End Namespace
I reliase this is an old subject, but this may help someone in future, make sure you compile in framework 3.5
Sorry cant seem to edit or delete my previous answer, for anyone in future, this should help:
Imports System
Imports System.Diagnostics
Imports DotNetOpenAuth.OAuth2
Imports Google.Apis.Authentication.OAuth2
Imports Google.Apis.Authentication.OAuth2.DotNetOpenAuth
Imports Google.Apis.Drive.v2
Imports Google.Apis.Drive.v2.Data
Imports Google.Apis.Util
Imports System.Security
Imports Google.Apis.Services
Public Class GoogleDrive
Public Function UploadFile() As Boolean
Const CLIENT_ID As String = "xxxxxxxxxxxxx.apps.googleusercontent.com"
Const CLIENT_SECRET As String = "-yyyyyyyyyyyyyyyyyyyyyyy"
'Register the authenticator and create the service
Dim provider As NativeApplicationClient = New NativeApplicationClient(GoogleAuthenticationServer.Description, CLIENT_ID, CLIENT_SECRET)
Dim getAuth As Func(Of NativeApplicationClient, IAuthorizationState) = AddressOf GetAuthorization
Dim auth As OAuth2Authenticator(Of NativeApplicationClient) = New OAuth2Authenticator(Of NativeApplicationClient)(provider, getAuth)
Dim service = New DriveService(New BaseClientService.Initializer() With {.Authenticator = auth})
Dim body As File = New File()
body.Title = "My document"
body.Description = "A test document"
body.MimeType = "text/plain"
Dim byteArray As Byte() = System.IO.File.ReadAllBytes("D:\document.txt")
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(byteArray)
Dim request As FilesResource.InsertMediaUpload = service.Files.Insert(body, stream, "text/plain")
request.Upload()
Dim file As File = request.ResponseBody
MessageBox.Show("File : " & file.Id)
End Function
Private Function GetAuthorization(ByVal Client As NativeApplicationClient) As IAuthorizationState
Dim RetVal As IAuthorizationState
Dim state As IAuthorizationState = New AuthorizationState(New String() {DriveService.Scopes.Drive.GetStringValue()})
'Check to see if we have a saved refresh token
If My.Settings.SavedAuth.ToString <> "" Then
state.RefreshToken = My.Settings.SavedAuth
If (Client.RefreshToken(state)) Then
Return state
End If
End If
'Get the auth URL:
state.Callback = New Uri(NativeApplicationClient.OutOfBandCallbackUrl)
Dim authUri As Uri = Client.RequestUserAuthorization(state)
'Request authorization from the user (by opening a browser window):
Process.Start(authUri.ToString())
'wait until user has entered the code
Dim authCode As String = InputBox("Authorisation code", "Authorisation Code", "")
'Retrieve the access token by using the authorization code:
RetVal = Client.ProcessUserAuthorization(authCode, state)
'store the refresh token
Call StoreRefreshToken(state.RefreshToken)
Return RetVal
End Function
Private Function LoadRefreshToken() As String
Return My.Settings.SavedAuth
End Function
Private Sub StoreRefreshToken(ByVal Token As String)
My.Settings("SavedAuth") = Token
My.Settings.Save()
End Sub
End Class

How to post XML document to HTTP with VB.Net

I'm looking for help with posting my XML document to a url in VB.NET. Here's what I have so far ...
Public Shared xml As New System.Xml.XmlDocument()
Public Shared Sub Main()
Dim root As XmlElement
root = xml.CreateElement("root")
xml.AppendChild(root)
Dim username As XmlElement
username = xml.CreateElement("username")
username.InnerText = _username
root.AppendChild(username)
xml.Save(Console.Out)
Dim url = "https://mydomain.com"
Dim req As WebRequest = WebRequest.Create(url)
req.Method = "POST"
req.ContentType = "application/xml"
req.Headers.Add("Custom: API_Method")
Console.WriteLine(req.Headers.ToString())
This is where things go awry:
I want to post the xml, and then print the results to console.
Dim newStream As Stream = req.GetRequestStream()
xml.Save(newStream)
Dim response As WebResponse = req.GetResponse()
Console.WriteLine(response.ToString())
End Sub
This is essentially what I was after:
xml.Save(req.GetRequestStream())
If you don't want to take care about the length, it is also possible to use the WebClient.UploadData method.
I adapted your snippet slightly in this way.
Imports System.Xml
Imports System.Net
Imports System.IO
Public Module Module1
Public xml As New System.Xml.XmlDocument()
Public Sub Main()
Dim root As XmlElement
root = xml.CreateElement("root")
xml.AppendChild(root)
Dim username As XmlElement
username = xml.CreateElement("username")
username.InnerText = "user1"
root.AppendChild(username)
Dim url = "http://mydomain.com"
Dim client As New WebClient
client.Headers.Add("Content-Type", "application/xml")
client.Headers.Add("Custom: API_Method")
Dim sentXml As Byte() = System.Text.Encoding.ASCII.GetBytes(xml.OuterXml)
Dim response As Byte() = client.UploadData(url, "POST", sentXml)
Console.WriteLine(response.ToString())
End Sub
End Module