mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-14 04:08:15 +08:00
fix(binding): improve empty slice/array handling in form binding (#4380)
Co-authored-by: huangzw <huangzw@2345.com>
This commit is contained in:
parent
9968c4bf9d
commit
c3d1092b3b
@ -231,9 +231,12 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][
|
||||
|
||||
switch value.Kind() {
|
||||
case reflect.Slice:
|
||||
if !ok {
|
||||
vs = []string{opt.defaultValue}
|
||||
if len(vs) == 0 {
|
||||
if !opt.isDefaultExists {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
vs = []string{opt.defaultValue}
|
||||
// pre-process the default value for multi if present
|
||||
cfTag := field.Tag.Get("collection_format")
|
||||
if cfTag == "" || cfTag == "multi" {
|
||||
@ -251,9 +254,12 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][
|
||||
|
||||
return true, setSlice(vs, value, field)
|
||||
case reflect.Array:
|
||||
if !ok {
|
||||
vs = []string{opt.defaultValue}
|
||||
if len(vs) == 0 {
|
||||
if !opt.isDefaultExists {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
vs = []string{opt.defaultValue}
|
||||
// pre-process the default value for multi if present
|
||||
cfTag := field.Tag.Get("collection_format")
|
||||
if cfTag == "" || cfTag == "multi" {
|
||||
|
@ -635,3 +635,83 @@ func TestMappingCustomArrayForm(t *testing.T) {
|
||||
expected, _ := convertTo(val)
|
||||
assert.Equal(t, expected, s.FileData)
|
||||
}
|
||||
|
||||
func TestMappingEmptyValues(t *testing.T) {
|
||||
t.Run("slice with default", func(t *testing.T) {
|
||||
var s struct {
|
||||
Slice []int `form:"slice,default=5"`
|
||||
}
|
||||
|
||||
// field not present
|
||||
err := mappingByPtr(&s, formSource{}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []int{5}, s.Slice)
|
||||
|
||||
// field present but empty
|
||||
err = mappingByPtr(&s, formSource{"slice": {}}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []int{5}, s.Slice)
|
||||
|
||||
// field present with values
|
||||
err = mappingByPtr(&s, formSource{"slice": {"1", "2", "3"}}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []int{1, 2, 3}, s.Slice)
|
||||
})
|
||||
|
||||
t.Run("array with default", func(t *testing.T) {
|
||||
var s struct {
|
||||
Array [1]int `form:"array,default=5"`
|
||||
}
|
||||
|
||||
// field not present
|
||||
err := mappingByPtr(&s, formSource{}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, [1]int{5}, s.Array)
|
||||
|
||||
// field present but empty
|
||||
err = mappingByPtr(&s, formSource{"array": {}}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, [1]int{5}, s.Array)
|
||||
})
|
||||
|
||||
t.Run("slice without default", func(t *testing.T) {
|
||||
var s struct {
|
||||
Slice []int `form:"slice"`
|
||||
}
|
||||
|
||||
// field present but empty
|
||||
err := mappingByPtr(&s, formSource{"slice": {}}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []int(nil), s.Slice)
|
||||
})
|
||||
|
||||
t.Run("array without default", func(t *testing.T) {
|
||||
var s struct {
|
||||
Array [1]int `form:"array"`
|
||||
}
|
||||
|
||||
// field present but empty
|
||||
err := mappingByPtr(&s, formSource{"array": {}}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, [1]int{0}, s.Array)
|
||||
})
|
||||
|
||||
t.Run("slice with collection format", func(t *testing.T) {
|
||||
var s struct {
|
||||
SliceMulti []int `form:"slice_multi,default=1;2;3" collection_format:"multi"`
|
||||
SliceCsv []int `form:"slice_csv,default=1;2;3" collection_format:"csv"`
|
||||
}
|
||||
|
||||
// field not present
|
||||
err := mappingByPtr(&s, formSource{}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []int{1, 2, 3}, s.SliceMulti)
|
||||
assert.Equal(t, []int{1, 2, 3}, s.SliceCsv)
|
||||
|
||||
// field present but empty
|
||||
err = mappingByPtr(&s, formSource{"slice_multi": {}, "slice_csv": {}}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []int{1, 2, 3}, s.SliceMulti)
|
||||
assert.Equal(t, []int{1, 2, 3}, s.SliceCsv)
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user