VBA-tools / VBA-JSON

JSON conversion and parsing for VBA
MIT License
1.77k stars 573 forks source link

Quotes in keys are not escaped #100

Open ramyaprabhakar opened 6 years ago

ramyaprabhakar commented 6 years ago

Hi, I am running into a problem I have no idea how to tackle.I need to construct a Json which looks like this to be passed as a request to get the sessionId as response: { "instruction":"login", "sessionId" : 0, "json": { "\"user\"":"\"xxxx\"", "\"password\"":"\"yyyy\"" } }

I'm currently passing the inner Json as Dictionary and collection parameters and then adding them to the request, but the request doesnt go in the above mentioned format whereas this is how its sent: "{"instruction":"login","sessionId":0,"json":"[{\"user\":\"xxxx\"},{\"password\":\"yyyy\"}]"}"

My code:


Function QuerySpa() As WebResponse Dim Client As New WebClient Dim Request As New WebRequest Client.BaseUrl = "http://localhost:8080/spa/api/login"

Dim c3 As Collection Dim j3 As Dictionary Dim j4 As Dictionary Set c3 = New Collection Set j3 = New Dictionary Set j4 = New Dictionary

j3.Add "user", "xxxx" j4.Add "password", "yyyy" c3.Add j3 c3.Add j4

Request.Method = WebMethod.HttpPost Request.ResponseFormat = WebFormat.JSON 'Request.Body = JsonString Request.AddBodyParameter "instruction", "login" Request.AddBodyParameter "sessionId", 0 Request.AddBodyParameter "json", JsonConverter.ConvertToJson(c3)

Set QuerySpa = Client.Execute(Request)

End Function


What is the best way to build the innerJson, If given as a string, then it is adding many //s and ""s which are very difficult to handle. Your help would be much appreciated.

Thanks in Advance Ramya

timhall commented 6 years ago

By calling ConvertToJson you are converting it into a string, which isn't what you want. Additionally, a Collection is converted into an array, which also isn't what you want.

With the following change you remove the quoted json value, which gets you closer:

Request.AddBodyParameter "json", c3

Debug.Print Request.Body
' {"instruction":"login","sessionId":0,"json":[{"user":"xxxx"},{"password":"yyyy"}]}

If you use a Dictionary instead of a Collection, you should get the format you are looking for:

Dim Json As New Dictionary
Json("user") = "xxxx"
Json("password") = "yyyy"

Request.AddBodyParameter "json", Json

Debug.Print Request.Body
' {"instruction":"login","sessionId":0,"json":{"user":"xxxx", "password":"yyyy"}}
ramyaprabhakar commented 6 years ago

Hi Tim, Thanks a lot for responding. Honor. I'm writing to you here as when i'm writing the following line(in red) in the github, it changes the backslashes to double quotes by default 🤔

The desired Json request in the first place has to look like this:

I did the following changes to my code after reading ur reply:

Dim Json As New Dictionary Json.Add JsonConverter.ConvertToJson("user"), JsonConverter.ConvertToJson("xxxx") Json.Add JsonConverter.ConvertToJson("password"), JsonConverter.ConvertToJson("yyyy")

Request.Method = WebMethod.HttpPost Request.ResponseFormat = WebFormat.Json Request.AddBodyParameter "instruction", "login" Request.AddBodyParameter "sessionId", 0 Request.AddBodyParameter "json", Json


The request that is going right now is {"instruction":"login","sessionId":0,"json":{""user"":"\"xxxx\"",""password"":"\"yyyy\""}}

This is almost right, the Dictionary "value" parameters when converted to Json are passing fine in the request, whereas the Dictionary " key" parameters are passing as ""user"" instead of "\"user\"" What do u think is happening while passing this in the webrequest? Is there any other way i should be constructing it?

Awaiting your response. It would be of much help. Thank You -Ramya

On Wed, Jun 6, 2018 at 12:26 AM, Tim Hall notifications@github.com wrote:

By calling ConvertToJson you are converting it into a string, which isn't what you want. Additionally, a Collection is converted into an array, which also isn't what you want.

With the following change you remove the quoted json value, which gets you closer:

Request.AddBodyParameter "json", c3 Debug.Print Request.Body' {"instruction":"login","sessionId":0,"json":[{"user":"xxxx"},{"password":"yyyy"}]}

If you use a Dictionary instead of a Collection, you should get the format you are looking for:

Dim Json As New DictionaryJson("user") = "xxxx"Json("password") = "yyyy" Request.AddBodyParameter "json", Json Debug.Print Request.Body' {"instruction":"login","sessionId":0,"json":{"user":"xxxx", "password":"yyyy"}}

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/VBA-tools/VBA-JSON/issues/100#issuecomment-394821798, or mute the thread https://github.com/notifications/unsubscribe-auth/AGZwAVI9XCA-0mXXn3hKnNqLBmAiCnrbks5t5tRbgaJpZM4UbWxW .

timhall commented 6 years ago

Hmm, that may be a bug. I'll look into how keys are escaped and see what I can find.

ramyaprabhakar commented 6 years ago

Hi Tim,

So looks like the request when passed this way to my Login API, fetched the desired response successfully

Dim strUser As String strUser = "{""user"":""xxxx"", ""password"":""yyyy""}"

Dim Request As New WebRequest Request.Method = WebMethod.HttpPost Request.ContentType = "application/json" Request.AddBodyParameter "instruction", "login" Request.AddBodyParameter "sessionId", 0 Request.AddBodyParameter "json", strUser

I was given the older Json from the java WebUI dev team and hence the confusion. Thanks So much.The above solution (inner Json as string) is working perfectly for me.

Thanks and Regards, Ramya

On Wed, Jun 6, 2018 at 7:15 PM, Tim Hall notifications@github.com wrote:

Reopened #100 https://github.com/VBA-tools/VBA-JSON/issues/100.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/VBA-tools/VBA-JSON/issues/100#event-1666170298, or mute the thread https://github.com/notifications/unsubscribe-auth/AGZwATmaE5fz6PsC8JDdxnnmzc9XYGrtks5t59zcgaJpZM4UbWxW .

slishak commented 5 years ago

I think there is still a problem with escape characters in object keys. The following subroutine illustrates the issue:

Sub BackslashTest()

    Dim json As New Dictionary

    json.Add "Test\Test", "Test\Test"
    Debug.Print JsonConverter.ConvertToJson(json)

End Sub

output: {"Test\Test":"Test\\Test"}

So the backslash in the value is correctly escaped, but the backslash in the key is not.

slishak commented 5 years ago

Seems to be fixed by https://github.com/VBA-tools/VBA-JSON/pull/122