-2

I programmed multiple methods for my handler which look like this for example:

func DeleteProduct(w http.ResponseWriter, r *http.Request){
    log.Println(r.Form)
    db.Exec("Delete from  products where Id = "+r.FormValue("Id"))
}

The problem is that r.Form is always an empty map, in my delete request I send the Id in a JSON which looks like this:

    {
        "CustomerDate": "13.03.2018",
        "CustomerDateTime": "13:30",
        "UserId": 4
    }

in the main method I register the handler methods like this:

        router.HandleFunc("/delete",handler.DeleteProduct).Methods("DELETE")

Why is the r.Form and the r.PostForm always an empty map?

Johannes Gnadlinger
  • 1,339
  • 1
  • 12
  • 32
  • 3
    https://golang.org/pkg/net/http/#Request.Form specifically this part *"This field is only available after ParseForm is called."* and btw `FormValue` should call `ParseForm` if it hasn't yet been. – mkopriva May 16 '18 at 12:43
  • 2
    Secondly, and more importantly Form does not contain json data. Form, after parsing, will hold data sent as `application/x-www-form-urlencoded` + data sent as query parameters, if no such data was sent then Form will be empty even after parse. – mkopriva May 16 '18 at 12:45
  • 2
    See here on how to get the json from a request https://stackoverflow.com/a/15685432/965900 – mkopriva May 16 '18 at 12:46
  • 5
    Not related to your question, but you're opening yourself up to a huge SQL injection attack this way. PLEASE use placeholders in your SQL queries instead of building a query with string concatenation. – Jonathan Hall May 16 '18 at 12:50
  • As @mkopriva states you require a call to `r.ParseForm ()` in order to populate data structures with actual values. From other side it would be good to see the client code in order to verify that your are sending properly the url params or body content – Victor May 16 '18 at 12:50
  • 2
    Posting a JSON document is not how HTML forms work. – Volker May 16 '18 at 12:58

1 Answers1

3

In case of JSON request you have to unmarshal request body before using any parameter.
For example:

type ReqBody struct {
  CustomerDateTime string `json:"CustomerDateTime"`
  CustomerDateTime string `json:"CustomerDateTime"`
  UserId           int    `json:"UserId"`
}

body, err := ioutil.ReadAll(req.Body)
if err != nil {
    // Error handler...
}
rb := ReqBody{}
json.Unmarshal(body, &rb)
// Now you can perform something like this:
println(rb.UserId)
cn007b
  • 16,596
  • 7
  • 59
  • 74