validation.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package gin
  2. import (
  3. "errors"
  4. "reflect"
  5. "strings"
  6. )
  7. func (c *Context) ErrorRender() HandlerFunc {
  8. return func(c *Context) {
  9. defer func() {
  10. if len(c.Errors) > 0 {
  11. c.JSON(-1, c.Errors)
  12. }
  13. }()
  14. c.Next()
  15. }
  16. }
  17. func Validate(c *Context, obj interface{}) error {
  18. var err error
  19. typ := reflect.TypeOf(obj)
  20. val := reflect.ValueOf(obj)
  21. if typ.Kind() == reflect.Ptr {
  22. typ = typ.Elem()
  23. val = val.Elem()
  24. }
  25. for i := 0; i < typ.NumField(); i++ {
  26. field := typ.Field(i)
  27. fieldValue := val.Field(i).Interface()
  28. zero := reflect.Zero(field.Type).Interface()
  29. // Validate nested and embedded structs (if pointer, only do so if not nil)
  30. if field.Type.Kind() == reflect.Struct ||
  31. (field.Type.Kind() == reflect.Ptr && !reflect.DeepEqual(zero, fieldValue)) {
  32. err = Validate(c, fieldValue)
  33. }
  34. if strings.Index(field.Tag.Get("binding"), "required") > -1 {
  35. if reflect.DeepEqual(zero, fieldValue) {
  36. name := field.Name
  37. if j := field.Tag.Get("json"); j != "" {
  38. name = j
  39. } else if f := field.Tag.Get("form"); f != "" {
  40. name = f
  41. }
  42. err = errors.New("Required " + name)
  43. c.Error(err, "json validation")
  44. }
  45. }
  46. }
  47. return err
  48. }