I am trying to send api request by VBA - MS Access 2016, in order to receive json file, when I implemented this I received the error message below
I am using Microsoft XML, V6 as reference
my code as below
Dim xml_obj As MSXML2.XMLHTTP60
'Create a new Request Object
Set xml_obj = New MSXML2.XMLHTTP60
'API code
api_url = Me.UPC
'Open a new request using our URL
xml_obj.Open bstrMethod:="GET", bstrURL:=api_url
'Send the request
xml_obj.send
Related
I have an excel sheet which is doing some matching from Quickbooks (hence the Excel).
I know I can pass "PUT" and "GET" calls using DOM and XMLHTTP but when I send the PUT I get the message back:
A content type for the input was not supplied.
Is this a syntax issue on my part? I've tried a few ways:
/api/v2/products/33288?"Content-Type":"application/json"&"condition":"Worn"
/api/v2/products/33288?"condition":"Worn"
/api/v2/products/33288,"condition":"Worn"
All with similar results.
If it doesn't show, I am not all that comfortable with API calls, but very comfortable with VBA
Full Code
Dim req As New XMLHTTP
Dim doc As New DOMDocument
Dim url As String
Dim nd As String
url = "https://USER:PASS#WEBSITE/api/v2/products/33288?""Content-Type"":""application/json""&""condition"":""Worn"""
req.Open "PUT", url, False
req.Send
doc.LoadXML req.ResponseText
doc.Save "C:\Users\Admin\Desktop\WebQueryResult2.xml"
The below code works on some URLs, but some other URLs having parameters return the error: The remote server returned an error: (405) Method Not Allowed.
my work:
Dim objHttpWebRequest As HttpWebRequest = Nothing
Dim objHttpWebResponse As HttpWebResponse = Nothing
Dim objRequestStream As Stream = Nothing
Dim objResponseStream As Stream = Nothing
Dim objXMLReader As XmlTextReader
Try
objHttpWebRequest = WebRequest.Create(URL)
'Start HttpRequest
objHttpWebRequest.Method = "POST"
objHttpWebRequest.ContentType = "application/xml"
'Get Stream Object
objRequestStream = objHttpWebRequest.GetRequestStream()
objRequestStream.Close()
'Start HTTP Response
objHttpWebResponse = objHttpWebRequest.GetResponse()
If objHttpWebResponse.StatusCode = HttpStatusCode.OK Then
objResponseStream = objHttpWebResponse.GetResponseStream()
objXMLReader = New XmlTextReader(objResponseStream)
Dim xmldoc As XmlDocument = New XmlDocument
xmldoc.Load(objXMLReader)
XMLResponse = xmldoc
objXMLReader.Close()
End If
Is the problem in the method I am using? or the content type?
Based on the status code, the problem is in the method. Not all of the URLs might be able to respond to POST requests.
Wikipedia states
405 Method Not Allowed
A request was made of a resource using a request method not supported
by that resource; for example, using GET on a form which requires data
to be presented via POST, or using PUT on a read-only resource.
I'm trying to upload a file from an FTP site to Basecamp using the Basecamp API. I'm using a simple console application. Here's my code:
Try
Dim accountID As String = ConfigurationManager.AppSettings("BaseCampID")
Dim projectID As Integer = 9999999
Dim folderName As String = "XXXXX/XXXXX"
Dim fileName As String = "XXX.zip"
'The URL to access the attachment method of the API
Dim apiURL = String.Format("https://basecamp.com/{0}/api/v1/projects/{1}/attachments.json", accountID, projectID)
'Get the file from the FTP server as a byte array
Dim fileBytes As Byte() = GetFileBytes(String.Format("{0}\\{1}", folderName, fileName))
'Initialize the WebClient object
Dim client As New WebClient()
client.Headers.Add("Content-Type", "application/zip")
'Need to provide a user-agent with a URL or email address
client.Headers.Add("User-Agent", "Basecamp Upload (email#email.com)")
'Keep the connection alive so it doesn't close
client.Headers.Add("Keep-Alive", "true")
'Provide the Basecamp credentials
client.Credentials = New NetworkCredential("username", "password")
'Upload the file as a byte array to the API, and get the response
Dim responseStr As Byte() = client.UploadData(apiURL, "POST", fileBytes)
'Convert the JSON response to a BaseCampAttachment object
Dim attachment As BaseCampAttachment
attachment = JSonHelper.FromJSon(Of BaseCampAttachment)(Encoding.Default.GetString(responseStr))
Catch ex As Exception
Console.WriteLine(ex.Message)
Finally
Console.ReadLine()
End Try
But whenever it calls client.UploadData, I get the error message "The underlying connection was closed: The connection was closed unexpectedly." I ran into this issue earlier and thought I solved it by adding the "Keep-Alive" header, but it's not working anymore. The API works if I upload a local file with client.UploadFile, but I'd like to just upload the file from they byte array from the FTP rather than downloading the file locally then uploading it to Basecamp.
Any thoughts would be greatly appreciated. Thanks!
I never figured out what was wrong with the WebClient call, but I ended up using a Basecamp API wrapper from https://basecampwrapper.codeplex.com. That wrapper uses HTTPRequest and HTTPResponse instead of WebClient.UploadData. It's also much easier to just use that wrapper than to try writing my own code from scratch.
I want to send a POST request to a Java servlet with VBA using the Kerberos ticket from the Windows Log In for authentication and then retrieve a JSON response from the servlet. Can I achieve this without using an InternetExplorer object, e.g. using WinHttpRequest?
WinHttpRequest is not an IE object. The above described usecase works perfectly as long as you set up to relax the security permissions. I have implemented a proof of concept last year: Excel, VBA, REST, Tomcat, SPNEGO authentication.
Stub code:
Dim winHttp As Object
Set winHttp = CreateObject("WinHttp.WinHttpRequest.5.1")
winHttp.SetAutoLogonPolicy (0)
winHttp.Open "GET", "http://..."
winHttp.send
Dim success As Boolean
success = winHttp.waitForResponse(5)
If Not success Then
Debug.Print "DOWNLOAD FAILED!"
Exit Sub
End If
Dim responseText As String
responseText = winHttp.responseText
I am making a Windows Phone app and I am trying to get JSON data from a URL. The user needs to be logged into the website (which hosts the JSON data) in order to get JSON data and I cannot use the Web Browser control to display the data and then extract the string since the browser doesn't recognize it (for some weird reason) and asks to search for an app on Store which can handle that JSON file type. (If I open the URL in desktop browser on my Windows PC, I can see the raw JSON data). I can't use normal HTTPWebRequest or WebClient as to get JSON data the login cookies needs to be set (the JSON data is user-specific) and I can't extract the cookies from Web browser control and use it with WebClient or HTTPWebRequest. So the best thing I can do is use a special internal instance of IWebRequestCreate that is used internally by the WebBrowser. By opening background HTTP requests with that class, the cookies get automatically set as if they were created/sent by the WebBrowser control. But my code is not returning the JSON data, I get blank response, as in the string resp is empty.
Below is the code:
Dim browser = New WebBrowser()
Dim brwhttp = GetType(WebRequestCreator).GetProperty("BrowserHttp")
Dim requestFactory = TryCast(brwhttp.GetValue(Browser, Nothing), IWebRequestCreate)
Dim uri = New Uri("http://api.quora.com/api/logged_in_user?fields=inbox,notifs,following,followers")
Dim req = requestFactory.Create(uri)
req.Method = "GET"
req.BeginGetResponse(New AsyncCallback(AddressOf request_Callback), req)
Private Sub request_Callback(asyncResult As IAsyncResult)
Dim webRequest As HttpWebRequest = DirectCast(asyncResult.AsyncState, HttpWebRequest)
Dim webResponse As HttpWebResponse = DirectCast(webRequest.EndGetResponse(asyncResult), HttpWebResponse)
Dim tempStream As New MemoryStream()
webResponse.GetResponseStream().CopyTo(tempStream)
Dim sr As New StreamReader(tempStream)
Dim resp As String = sr.ReadToEnd
End Sub
What's wrong?
I found that CopyTo can leave the Stream's pointer at the end of the buffer, you probably need to reset tempStream's pointer to the beginning before attempting to read it with the StreamReader, here's the code...
webResponse.GetResponseStream().CopyTo(tempStream);
tempStream.Seek(0, SeekOrigin.Begin);
Dim sr As New StreamReader(tempStream);