github.com/songzhibin97/gkit@v1.2.13/tools/bind/multlpart_form_mapping.go (about) 1 package bind 2 3 import ( 4 "errors" 5 "mime/multipart" 6 "net/http" 7 "reflect" 8 ) 9 10 type multipartRequest http.Request 11 12 var _ setter = (*multipartRequest)(nil) 13 14 // TrySet tries to set a value by the multipart request with the binding a form file 15 func (r *multipartRequest) TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (isSetted bool, err error) { 16 if files := r.MultipartForm.File[key]; len(files) != 0 { 17 return setByMultipartFormFile(value, field, files) 18 } 19 20 return setByForm(value, field, r.MultipartForm.Value, key, opt) 21 } 22 23 func setByMultipartFormFile(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSetted bool, err error) { 24 // 判断value 类型 25 switch value.Kind() { 26 case reflect.Ptr: 27 switch value.Interface().(type) { 28 case *multipart.FileHeader: 29 value.Set(reflect.ValueOf(files[0])) 30 return true, nil 31 } 32 case reflect.Struct: 33 switch value.Interface().(type) { 34 case multipart.FileHeader: 35 value.Set(reflect.ValueOf(*files[0])) 36 return true, nil 37 } 38 case reflect.Slice: 39 slice := reflect.MakeSlice(value.Type(), len(files), len(files)) 40 isSetted, err = setArrayOfMultipartFormFiles(slice, field, files) 41 if err != nil || !isSetted { 42 return isSetted, err 43 } 44 value.Set(slice) 45 return true, nil 46 case reflect.Array: 47 return setArrayOfMultipartFormFiles(value, field, files) 48 } 49 return false, errors.New("unsupported field type for multipart.FileHeader") 50 } 51 52 func setArrayOfMultipartFormFiles(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSetted bool, err error) { 53 if value.Len() != len(files) { 54 return false, errors.New("unsupported len of array for []*multipart.FileHeader") 55 } 56 for i := range files { 57 setted, err := setByMultipartFormFile(value.Index(i), field, files[i:i+1]) 58 if err != nil || !setted { 59 return setted, err 60 } 61 } 62 return true, nil 63 }