gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
78.28k stars 7.99k forks source link

Json binding doesn't work #3339

Open tiredsosha opened 2 years ago

tiredsosha commented 2 years ago

Description

I tried my own variation + default from readme. Always the same error
{"error":"invalid character 'u' looking for beginning of object key string"}

To be honest i don't now wht to do anymore

How to reproduce

package main 

import "github.com/gin-gonic/gin"
type Login struct {
  User     string `form:"user" json:"user" xml:"user"  binding:"required"`
  Password string `form:"password" json:"password" xml:"password" binding:"required"`
}

func main() {
  router := gin.Default()

  // Example for binding JSON ({"user": "manu", "password": "123"})
  router.POST("/loginJSON", func(c *gin.Context) {
    var json Login
    if err := c.ShouldBindJSON(&json); err != nil {
      c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
      return
    }

    if json.User != "manu" || json.Password != "123" {
      c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
      return
    }

    c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
  })

  // Listen and serve on 0.0.0.0:8080
  router.Run(":8080")
}

Environment

the-hotmann commented 2 years ago

Your JSON is invalid.

You need to escape the quotes.

Exampel 1 (invalid):

curl -X POST https://domain.de/loginJSON -H "Content-Type: application/json" -d "{"user": "manu", "password": "123"}"

Response: {"error":"invalid character 'u' looking for beginning of object key string"}

Exampel 2:

curl -X POST https://domain.de/loginJSON -H "Content-Type: application/json" -d "{\"user\": \"manu\", \"password\": \"123\"}"

Response: {"status":"you are logged in"}

Have fun!

tiredsosha commented 2 years ago

omg, that's work, thanks.
I just don't understand why first one isn't working? It's valid json. I tried to read from file, send with python script. This is how json file looks like:
{ "name": "manu", "password": "123" }

Your JSON is invalid.

You need to escape the quotes.

Exampel 1 (invalid):

curl -X POST https://domain.de/loginJSON -H "Content-Type: application/json" -d "{"user": "manu", "password": "123"}"

Response: {"error":"invalid character 'u' looking for beginning of object key string"}

Exampel 2:

curl -X POST https://domain.de/loginJSON -H "Content-Type: application/json" -d "{\"user\": \"manu\", \"password\": \"123\"}"

Response: {"status":"you are logged in"}

Have fun!

the-hotmann commented 2 years ago

It reads in in as a string, which then is again placed in quotes.

So your JSON { "name": "manu", "password": "123" } becomes: "{ "name": "manu", "password": "123" }" which now needs escaping for all inner quotes.

If you covert it in backticks `{ "name": "manu", "password": "123" }` you probably don't need to escape. But I recommend you escaping it.

tech-sumit commented 2 years ago

@tiredsosha @MartinHotmann just by updating curl from

curl -X POST https://domain.de/loginJSON -H "Content-Type: application/json" -d "{"user": "manu", "password": "123"}"

to

curl -X POST http://localhost:8080/loginJSON -H "Content-Type: application/json" -d '{"user": "manu", "password": "123"}'

works perfectly. just replaced double quotes " by single quote ' in -d flag