Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

binding issue with multipart form #398

Closed
TheInsideMan opened this issue Aug 4, 2015 · 13 comments
Closed

binding issue with multipart form #398

TheInsideMan opened this issue Aug 4, 2015 · 13 comments

Comments

@TheInsideMan
Copy link

Hello Im getting the below error. This error has only started since switching to a multipart form with file being posted. Any advice much appreciated.

$ curl -X POST --form "icon=@ak2.jpg"  --cookie 'session=91b5sdfdsfdsm' "http://127.0.0.1:8080/v1.0/apps" --form data='{"json_name":"test json name","title":"Test"}'
Panic recovery -> reflect: NumField of non-struct type
/usr/local/go/src/runtime/panic.go:387 (0x40145d8)
    gopanic: reflectcall(unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
/usr/local/go/src/reflect/type.go:657 (0x416ffca)
    (*rtype).NumField: panic("reflect: NumField of non-struct type")
/usr/local/go/src/src/github.com/gin-gonic/gin/binding/form_mapping.go:16 (0x4162831)
    mapForm: for i := 0; i < typ.NumField(); i++ {
/usr/local/go/src/src/github.com/gin-gonic/gin/binding/form.go:20 (0x4162693)
    formBinding.Bind: if err := mapForm(obj, req.Form); err != nil {
<autogenerated>:2 (0x4163e77)
/usr/local/go/src/src/github.com/gin-gonic/gin/context.go:244 (0x40851e2)
    (*Context).BindWith: if err := b.Bind(c.Request, obj); err != nil {
/usr/local/go/src/src/gin-api/controllers/apps.go:1119 (0x405fe68)
    CreateApps: c.BindWith(&json_tmp, binding.Form)
func CreateApps(c *gin.Context) {
    var json_tmp map[string]interface{}
    c.Bind(&json_tmp)
    ...
}
@TheInsideMan TheInsideMan changed the title binding issue binding issue with multipart form Aug 4, 2015
@z0rr0
Copy link

z0rr0 commented Aug 8, 2015

Hello,
I have a same problem but for simple HTTP form, it occurs always.

type Form struct {
    Token   string `form:"token" binding:"required"`
    Content string `form:"content" binding:"required"`
    Info    string `form:"info"`
    Wait    uint   `form:"wait"`
}

// handler code
form := &Form{}
if c.Bind(&form) != nil {
    // handling
}
/go/src/runtime/panic.go:387 (0x413ec8)
        gopanic: reflectcall(unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
/go/src/reflect/type.go:657 (0x4e31da)
        (*rtype).NumField: panic("reflect: NumField of non-struct type")
/project/src/github.com/gin-gonic/gin/binding/form_mapping.go:16 (0x5ba0f1)
        mapForm: for i := 0; i < typ.NumField(); i++ {
/project/src/github.com/gin-gonic/gin/binding/form.go:22 (0x5b9f53)
        formBinding.Bind: if err := mapForm(obj, req.Form); err != nil {
<autogenerated>:2 (0x5bb7a7)
/project/src/github.com/gin-gonic/gin/context.go:270 (0x4badc2)
        (*Context).BindWith: if err := b.Bind(c.Request, obj); err != nil {
/project/src/github.com/gin-gonic/gin/context.go:259 (0x4bac7e)
        (*Context).Bind: return c.BindWith(obj, b)
/project/src/myproject/utils/utils.go:159 (0x4b734f)
        HandlerForward: if c.Bind(&form) != nil {

@mr-linch
Copy link

@z0rr0 you pass pointer to pointer, but need just pointer:

type Form struct {
    Token   string `form:"token" binding:"required"`
    Content string `form:"content" binding:"required"`
    Info    string `form:"info"`
    Wait    uint   `form:"wait"`
}

// handler code
form := &Form{}
if c.Bind(form) != nil {
    // handling
}

@z0rr0
Copy link

z0rr0 commented Sep 22, 2016

@mr-linch oh, thanks 😃

@littletwolee
Copy link

Hi gays ,I have a error like @TheInsideMan
var user map[string]interface{}
err = c.Bind(user)

if I use map the error is:
// reflect: call of reflect.Value.Elem on map Value
and if use point ,the error is
//reflect: NumField of non-struct type
any body can help me? Thx a lot

@easonlin404
Copy link
Contributor

@littletwolee could you post your sample code to reproduce issue?

@littletwolee
Copy link

@easonlin404
like these
var (
//idstr, name, pwd string
err error
id int
user map[string]interface{}
)
err = c.Bind(&user)
err = modules.Test.UpdateUser(id, user)
if err != nil {
goto ERR
}
the error is "reflect: NumField of non-struct type"

if modify the code from "c.Bind(&user)" to "c.Bind(user)"
the error is "reflect: call of reflect.Value.Elem on map Value"

my struct is
type User struct {
ID int json:"id" form:"id"
Name string json:"name" form:"name" binding:"required"
Pwd string json:"pwd" form:"pwd" binding:"required"
}

can you guys help me? Thx a lot

@easonlin404
Copy link
Contributor

@littletwolee gin are assuming the binding is using structs only, so you have to use struct instead of map just like:

package main

import (
	"github.com/gin-gonic/gin"
)

type User struct {
	ID   int    `json:"id" form:"id"`
	Name string `json:"name" form:"name" binding:"required"`
	Pwd  string `json:"pwd" form:"pwd" binding:"required"`
}

var (
	err error
	id  int
	// user map[string]interface{} //you can't binding with map
)

func main() {
	r := gin.New()

	r.GET("/", func(c *gin.Context) {
		var user User
		err = c.Bind(&user)

		if err != nil {
			//...omitted
		}

		//...omitted
	})

	r.Run()
}

@littletwolee
Copy link

thx @easonlin404, But I think this is a missing func. I need to have more rules with our fontend. It's very crazy.T.T

@easonlin404
Copy link
Contributor

easonlin404 commented Jun 18, 2017

@littletwolee What's your scenario? You want to dynamically binding with params?

@littletwolee
Copy link

@easonlin404 Yep.I want get params is simply. Like map. I think request or form params were kv pairs. So, use map or struct were all good.

@littletwolee
Copy link

littletwolee commented Jun 19, 2017

@easonlin404 Mumm.I have a scenario.
my struct like this

type user struct {
      Name string
      Pwd   string 
}

Ok, Now I get a Http PUT request, It want to modify Name only.And I usr org package to control it.If I give orm a struct, it will change all fields. The param Pwd will be change from "xxx" to "".But I only to change Name.
So I want have a map[string]interface{} to complete it.
Like this. I'm not make sure you was clearly. My english is not good, thx a lot !!!

@thinkerou
Copy link
Member

@TheInsideMan @littletwolee If you use form post map, please see #1387 , thanks a lot!

@thinkerou
Copy link
Member

#1749 merged!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants