Click here to Skip to main content
15,888,984 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm working on a project to get a client's data via a vb.net watcher program to a web service. I didn't write the web side or the API for it. I have access to those developers but I'm stuck on something they are not versed in. I've tested my json in jsonlint and it's perfect. My connection code is fine too. I've tested that using a test API they created. There's something else going on that I'm missing. I'm getting a "bad request" error when I run their upload data API. No details. That's all it's returning to me. They've successfully tested it on their end using a different front end but I'm doing my part in vb.net.

Edit: I should note that when I use one of the API's they provide to pull data OUT of their system, that works fine. I can retrieve what I need. In that case I don't need the lines that deal with passing the json block (the GetRequestStream related stuff). I must be doing something wrong with respect to that.

Edit (2019-03-01): Note that I had found some variations on my code and tried them as well, such as what's shown here. There are other similar strategies that claim to work. I could not get that strategy to work either. I'm getting the same error as the person who posted that ticket.

What I have tried:

Here's my code:

VB
Dim hwReq As HttpWebRequest = Nothing
Dim hwResp As HttpWebResponse = Nothing

Try

    Dim noticeDataBodyContentBytes As Byte() = System.Text.Encoding.Unicode.GetBytes(noticeDataBodyContent)

    hwReq = HttpWebRequest.CreateHttp(webPortalURI)
    hwReq.Method = "POST"
    hwReq.ContentType = "application/json; charset=unicode"
    hwReq.ContentLength = noticeDataBodyContentBytes.Length
    hwReq.Accept = "application/json"
    hwReq.Headers.Add("timestamp", ts)
    hwReq.Headers.Add("apiclient", My.Settings.WebPortalClientID)
    hwReq.Headers.Add("apitoken", atkn)

    Dim noticeDataBodyContentStream As Stream = hwReq.GetRequestStream()
    noticeDataBodyContentStream.Write(noticeDataBodyContentBytes, 0, noticeDataBodyContentBytes.Length)
    noticeDataBodyContentStream.Close()

    hwResp = CType(hwReq.GetResponse, HttpWebResponse) '<<<<< error is here


Catch ex As Exception
    xfrmMain.memWatcherActivity.Text = "ERROR (" & DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") & "): " & friendlyErrorMessage & " - see log file for more info" & vbCrLf & xfrmMain.memWatcherActivity.Text
    errorMessageToLog = "ERROR: " & friendlyErrorMessage & " - " & ex.Message & vbCrLf & ex.StackTrace & vbCrLf & "(" & MethodBase.GetCurrentMethod().ReflectedType.FullName & ".vb." & MethodBase.GetCurrentMethod().Name & ")"
    Utilities.LogToFile(errorMessageToLog)
    If My.Settings.DevMode Then
        MessageBox.Show(errorMessageToLog, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    Else
        SendEmailMessage("ERROR: " & friendlyErrorMessage, errorMessageToLog, emergencyEmailPersonsArray)
    End If

Finally
    If hwResp IsNot Nothing Then
        hwResp.Close()
        hwResp.Dispose()
        hwResp = Nothing
    End If
    hwReq = Nothing

End Try


I don't get a response when the error occurs. It jumps to my exception handler.

My json block is in the noticeDataBodyContent variable. Like I said, I tested the json in jsonlint and it's perfect.

Hoping someone can let me know what I'm doing wrong here.

Thanks in advance!

Keith

Edit (2019-03-01): I changed my strategy to HttpClient and I got a little further. Instead of the above, I'm doing this now:

VB
Dim hc As New HttpClient
hc.DefaultRequestHeaders.Add("timestamp", ts)
hc.DefaultRequestHeaders.Add("apiclient", My.Settings.WebPortalClientID)
hc.DefaultRequestHeaders.Add("apitoken", atkn)
Dim u As New Uri(webPortalURI)
Dim sc As New StringContent(noticeDataBodyContent, Encoding.UTF8, "application/json")
Dim resp = hc.PostAsync(u, sc)
resp.Wait()


This is what I get back now:

{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Vary: Accept-Encoding
Vary: origin
Vary: accept-encoding
Cache-Control: no-cache
Date: Fri, 01 Mar 2019 14:17:50 GMT
Server: nginx/1.15.8
Content-Length: 65
Content-Type: application/json; charset=utf-8
}}
Posted
Updated 5-Mar-19 8:06am
v4
Comments
MadMyche 28-Feb-19 22:09pm    
You can show what Exception ex is bringing bacK?
avianrand 28-Feb-19 22:29pm    
Sorry. I mostly did above. There's really not much more to it that's useful. Here it is though:

"The remote server returned an error: (400) Bad Request."
Richard Deeming 5-Mar-19 13:54pm    
Try using something like Fiddler[^] to examine the request and response, to see if that gives you or the API developers any clues.

Unfortunately, a "400 Bad Request" error doesn't really give us anything to go on.
Graeme_Grant 5-Mar-19 22:40pm    
There should be an inner error message with more information. My guess is that you have not authenticated or missing a bearer token in the header ...

Looks to me you're closing the stream before you are finished with it.
noticeDataBodyContentStream.Close()

hwResp = CType(hwReq.GetResponse, HttpWebResponse) '<<<<< error is here
 
Share this answer
 
Comments
avianrand 1-Mar-19 6:54am    
All the examples I found online do the same thing. They close it before the GetResponse. And when I don't close it first, I get the exact same error.
This is working now. Pretty much all my code was exactly right. The only issue was that I should have been using UTF8 here instead of Unicode for the json body. Their error handling on the other end is not sufficient and no matter what I send, if it's bad somehow, is "bad request" with no other details. It's ridiculous.

VB.NET
Dim noticeDataBodyContentBytes As Byte() = System.Text.Encoding.Unicode.GetBytes(noticeDataBodyContent)


VB.NET
Dim noticeDataBodyContentBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(noticeDataBodyContent)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900