2

I am creating a web request of type POST but the converted JSON is not in the correct format. Below is my function:

Public Function CreateWebRequestPOST(ByVal strURL As String, objInput As Object) As JArray
        Try
            'Serialize the posted data & convert to bytes
            Dim inputJson = (New JavaScriptSerializer()).Serialize(objInput)
            Dim bytes As Byte() = Encoding.UTF8.GetBytes(inputJson)

            Dim request As HttpWebRequest = DirectCast(WebRequest.Create(strURL), HttpWebRequest)
            request.Method = "POST"
            request.ContentType = "application/json"
            request.Accept = "application/json"
            request.ContentLength = bytes.Length
            request.Expect = "application/json"
            request.GetRequestStream().Write(bytes, 0, bytes.Length)

            Dim username = "username"
            Dim password = "passoword"
            request.Credentials = New NetworkCredential(username, password)


            Using response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
                Dim reader As StreamReader
                Dim rawresp As String
                reader = New StreamReader(response.GetResponseStream())
                rawresp = reader.ReadToEnd()
                Dim array As JArray = JArray.Parse(rawresp)
                reader.Close()
                response.Close()
                Return array
            End Using
        Catch ex As Exception
            Dim empty As New JArray
            Return empty
        End Try
    End Function

The Object I am sending in the parameter is as follows:

Dim objReq As New RequestBodyList
Dim orderlist As New OrderList

orderlist.currency = "test"
orderlist.id = "test"
orderlist.amount = 100

objReq.apiOperation = "some_action"
objReq.order = orderlist


Dim response = main.CreateWebRequestPOST("some_URL", objReq)

Public Class RequestBodyList
    Public Property apiOperation() As String
    Public Property order() As New OrderList
End Class

Public Class OrderList
    Public Property currency() As String
    Public Property id() As String
    Public Property amount() As Integer
End Class

Below is a sample output for the inputJSON variable:

"{""apiOperation"":""Some_action"",""order"":{""currency"":""USD"",""id"":""test1234"",""amount"":100}}"

It looks like the converted JSON is not a correct format. What was done wrong here? What caused the double quotes to appear?

This is how the Request body should be sent:

Request body (JSON object)

{ 
    "apiOperation": "some_action", 
    "order": {
        "currency": "USD",
        "id": "some_order_id" ,
        "amount": 50
    } 
}
Rami Zebian
  • 539
  • 1
  • 5
  • 23
  • 1
    The repeated quotes are how VB escapes a quotation mark. The contents of the string are `{"apiOperation":"Some_action",...}`. It looks correct to me, are you having problems with receiving it on the other end? – Craig Jun 20 '19 at 13:04
  • The data should be sent in JSON format, however, if I paste this into a JSON validator it says that this is not a valid JSON. Yes, problems receiving it. @Craig – Rami Zebian Jun 20 '19 at 13:12
  • Well, yes, if you paste it as-is, the validator won't like it. That's because you're pasting a string specifically formatted for VB into something that doesn't do VB. You need to try the string without the escapes---I don't remember if the watch window will work for this, or if you need to use the magnifying glass watch widget. I don't think the problem is the json going out, though, by inspection it looks OK. Have you looked at what's coming in on the other end? – Craig Jun 20 '19 at 13:20
  • I just noticed the the "rawresp" is returning the response as wanted. The problem is converting into Jarray. I am getting this exception: {"Error reading JArray from JsonReader. Current JsonReader item is not an array: StartObject. Path '', line 1, position 1."} @Craig – Rami Zebian Jun 20 '19 at 13:35
  • So it seems like the problem is with the json coming back in. Can you post that? – Craig Jun 20 '19 at 13:39
  • 1
    I found the problem. The return type of the function should be of type object. So, I replaced Dim array As JArray = JArray.Parse(rawresp) by Dim array As JObject = JObject.Parse(rawresp) @Craig – Rami Zebian Jun 20 '19 at 13:41

2 Answers2

4
Public Function CreateWebRequestPOST(ByVal strURL As String, objInput As Object) As JObject
        Try
            'Serialize the posted data & convert to bytes
            Dim inputJson = (New JavaScriptSerializer()).Serialize(objInput)
            Dim bytes As Byte() = Encoding.UTF8.GetBytes(inputJson)

            Dim request As HttpWebRequest = DirectCast(WebRequest.Create(strURL), HttpWebRequest)
            request.Method = "POST"
            request.ContentType = "application/json"
            request.Accept = "application/json"
            request.ContentLength = bytes.Length
            request.Expect = "application/json"
            request.GetRequestStream().Write(bytes, 0, bytes.Length)

            Dim username = "username"
            Dim password = "passoword"
            request.Credentials = New NetworkCredential(username, password)


            Using response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
                Dim reader As StreamReader
                Dim rawresp As String
                reader = New StreamReader(response.GetResponseStream())
                rawresp = reader.ReadToEnd()
                Dim array As JObject = JObject.Parse(rawresp)
                reader.Close()
                response.Close()
                Return array
            End Using
        Catch ex As Exception

        End Try
    End Function

Ended up realizing that the return type should be of type Object and not Jarray.

Rami Zebian
  • 539
  • 1
  • 5
  • 23
0

cant comment so have to put it in as an answer! Can you give a bit more details. When you say...

Below is a sample output for the inputJSON variable:

Can you confirm what you think it wrong with the format as to my limited experience it just looks ok.

Below is a code snippet from one of my projects and how I process the JSON output to a stream reader and then use JsonConvert.DeserializeObject, bit round about but it dose the job and it ends up being more readable.

Hope it helps, R

Function test()

    Try

        'Get obligations
        Dim origResponse As HttpWebResponse
        Dim AccessToken As String = Access_Token
        Dim origRequest As HttpWebRequest = Nothing

        origRequest = DirectCast(HttpWebRequest.Create("https://api.service.hmrc.gov.uk/organisations/vat/" + CoVRN + "/obligations?from=2019-01-01&to=" + Now.ToString("yyyy-MM-dd") + "&status=O"), HttpWebRequest) 'for testing

        origRequest.Accept = "application/vnd.hmrc.1.0+json"
        origRequest.Headers.Add("Authorization", "Bearer " + AccessToken)
        origRequest.Method = "GET"
        origResponse = DirectCast(origRequest.GetResponse(), HttpWebResponse)
        Dim reader As IO.StreamReader = New IO.StreamReader(origResponse.GetResponseStream(), Text.Encoding.Default)
        Dim content As String = reader.ReadToEnd()
        Dim myResults = JsonConvert.DeserializeObject(Of RootObligation)(content)


    Catch webEx As WebException
        Dim errorMessage As String = webEx.Message
        Dim errorStack As String = webEx.StackTrace
        Dim stream = webEx.Response.GetResponseStream()
        Dim reader = New StreamReader(stream)
        Dim ReadableError As String = reader.ReadToEnd().ToString
        Dim myResults = JsonConvert.DeserializeObject(Of RootError)(ReadableError)

    Catch ex As Exception
        Dim errorMessage As String = ex.Message
        Dim errorStack As String = ex.StackTrace

        Session("message") = "Error in submission ex:" + ex.Message + " " + errorStack
        Return RedirectToAction("VATSubmission", "Transaction")

    End Try

End Function
Richard
  • 33
  • 7