Placing 'required' on a struct doesn't prevent the request from going through. I'm getting some strange behavior with binding in general.
Here is a function:
func CreateTag(c *gin.Context) {
var ntf NewForm
c.Bind(&ntf)
if ntf.Name == "" {
c.JSON(400, gin.H{"error_message": "tag name required"})
return
}
Presumably if the item is not present in the request, c.Fail should be returning 'Error #01: Required Type' in the response. Yet this does not happen, it passes straight to the conditional (which defeats the whole purpose of validate):
HTTP/1.1 400 Bad Request
Server: nginx
Date: Wed, 10 Sep 2014 00:18:29 GMT
Content-Type: application/json
Content-Length: 38
Connection: keep-alive
{"error_message":"tag name required"}
The error does show up in the gin logs, however:
[GIN] 2014/09/09 - 20:18:29 | 400 | 174.682us | 172.4.231.9 POST /new
Error #01: Required Type
Meta: Operation aborted
It also doesn't return correctly for an unknown MIME type:
[GIN] 2014/09/09 - 20:18:53 | 400 | 46.372us | 172.4.231.9 POST /new
Error #01: unknown content-type: pplication/json
Meta: Operation aborted
I get the same response from the server, it passes straight through.
Comment From: JimmyPettersson85
Possible duplicate of #100?
Comment From: techjanitor
I'm just using a simple struct here:
type NewForm struct {
Name string `json:"name" binding:"required"`
Type int `json:"type" binding:"required"`
}
Comment From: badoet
hmm i tot its suppose to be
if !c.Bind(&ntf) {
// error message
}
the bind will return bool result..
Comment From: techjanitor
That doesn't seem to do anything either ;D
Comment From: badoet
oh another thing, how r u posting the request data. is it in the request body / post form ? post form will not be detected by the c.Bind . u need to manually parse the form data one by one. the bind will only work if the data is in the request body. - things like angularjs automatically perform the correct way
Comment From: techjanitor
It's from AngularJS using ng-resource, json input.
Here is an example:
http://pastebin.com/raw.php?i=QL8ZeHW5
curl -i -H "Content-Type: application/json" -d '{}' ~:5000/post [22:00:23]
HTTP/1.1 400 Bad Request
Content-Type: application/json
Date: Tue, 23 Sep 2014 03:00:23 GMT
Content-Length: 34
{"error_message":"post required"}
Like I said it's setting the response code correctly and spitting out an error in the logs, so it's clearly working. It just doesn't stop the request?
Comment From: themartorana
@techjanitor it's still up to you to stop the execution of the request with a simple statement, such as
if !c.Bind(&ntf) {
c.Fail(...)
return
}
There's nothing short of a panic that could stop the execution of a handler.
Comment From: techjanitor
Then that should be in the example. What other purpose does Validate serve if it doesn't stop the request? Binding in Martini will stop the request, so I assumed that was the functionality. It seems to be implied:
If a field is decorated with binding:"required" and has a empty value when binding, the current request will fail with an error.
Comment From: osiloke
I ran into this, and i'm glad i found this post cause i just started using go today and i thought i broke something. Yep, the docs should be updated, and thankfully this is an opensource project, we the community can submit pull requests. It is a bit confusing though, because it is assumed that c.Bind does validation, but it really doesn't. It is used however to marshal the json/form post. You will need some other validation package for that, which i believe the author mentioned as a TODO. This is where i believe gin would start loosing speed and becoming more and more like martini.
Some struct validation, github.com/go-validator/validator
Comment From: techjanitor
That is not correct, please read the OP. Gin binding quite literally has a validate function. I invite you to look at binding.go and read the function.
https://github.com/gin-gonic/gin/blob/develop/binding/binding.go
In addition the documentation says, without any ambiguity, that bind will validate the input and stop the request.
You can also specify that specific fields are required. If a field is decorated with binding:"required" and has a empty value when binding, the current request will fail with an error.
Gin binding features validation. It spits output to the log but fails to stop the function. It is a broken feature.
Comment From: osiloke
Ha, i may have rambled, too much, but i was essentially agreeing with you but suggested that someone around here would probably fix it. I however never took a look at the binding.go code to see the validate function. I've only been on this go thing for a handful of hours, still getting up to speed. Thanks for the note though.
Comment From: davisford
Why was this issue closed? I'm having a similar problem where c.Bind() does not fail with invalid input. The api has also changed so Bind()
now returns an error
instead of a bool
.
It appears that gin uses this validator as it's default, but it does not appear to run for me when I send in JSON with missing tags that are required
.
EDIT: now I see, only the binding
tag works. I presumed the validate
tag would work as it seems to use that other library (noted above). I suppose with some further digging there's a way to plug in the bluesuncorp/validator so those tags are available?
type Foo struct {
//Name string `validate:"required"` // does not work
Name string `binding:"required" // does work
}
Comment From: nazwa
This is an old issue and like you said, the binding tags do work. ~~Seems like the docs still need to be updated.~~
Comment From: luongs3
still got trouble with Form Binding
Comment From: SharkFourSix
Bump. Invalid input just crosses path the validator like it's not there when it should fail.