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

An error occurred when the url variable parameter was used with c.bind(slice) #1638

Closed
3 tasks done
elissa2333 opened this issue Sep 13, 2020 · 6 comments
Closed
3 tasks done

Comments

@elissa2333
Copy link

elissa2333 commented Sep 13, 2020

Issue Description

An error occurred when the url variable parameter was used with c.bind(slice)

Checklist

  • Dependencies installed
  • No typos
  • Searched existing issues and docs

Expected behaviour

The binding result is consistent with the fixed url

Actual behaviour

raise error: binding element must be a struct

Steps to reproduce

pass: curl -X POST -H "Content-Type: application/json" -d '[{"id":2333}]' localhost:1323/a
fail: curl -X POST -H "Content-Type: application/json" -d '[{"id":2333}]' localhost:1323/b

Working code to debug

package main

import (
	"github.com/labstack/echo/v4"
	"net/http"
)

type Test struct {
	ID int `json:"id"`
}

func main() {
	e := echo.New()

	e.POST("/a", handle)

	// :name = b
	e.POST("/:name", handle) // -> error: binding element must be a struct
	e.Logger.Fatal(e.Start(":1323"))
}

func handle(c echo.Context) error {
	var m []*Test
	if err := c.Bind(&m); err != nil {
		return c.JSON(http.StatusBadRequest, echo.Map{"error": err})
	}

	return c.JSON(http.StatusOK, m)
}

Version/commit

github.com/labstack/echo/v4 v4.1.17

@elissa2333
Copy link
Author

The echo version returns to 4.0.0 and works normally

@rdiek
Copy link

rdiek commented Oct 5, 2020

fixed this problem for me:

git diff bind.go
diff --git a/bind.go b/bind.go
index f891474..9b94326 100644
--- a/bind.go
+++ b/bind.go
@@ -90,6 +90,10 @@ func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag
        typ := reflect.TypeOf(ptr).Elem()
        val := reflect.ValueOf(ptr).Elem()

+       // Slice (dont work in it)
+       if typ.Kind() == reflect.Slice {
+               return nil
+       }
        // Map
        if typ.Kind() == reflect.Map {
                for k, v := range data {

@elissa2333
Copy link
Author

Thank you

@aldas
Copy link
Contributor

aldas commented Oct 27, 2020

Can confirm that this bug is in v4.1.17

import (
	"github.com/labstack/echo/v4"
	"log"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
)

type Element struct {
	ID int `json:"id"`
}

func TestExample(t *testing.T) {
	e := echo.New()
	req := httptest.NewRequest(http.MethodGet, "/api/endpoint?lang=en", strings.NewReader(`[{"id": 1}]`))
	req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
	rec := httptest.NewRecorder()
	c :=  e.NewContext(req, rec)

	err := handle(c)
	if err != nil {
		t.Fatal(err)
	}
	response := string(rec.Body.Bytes())
	if strings.Contains(response, "binding element must be a struct"){
		t.Fatal(response)
	}
}

func handle(c echo.Context) error {
	var payload []Element
	if err := c.Bind(&payload); err != nil {
		return c.JSON(http.StatusBadRequest, echo.Map{"error": err})
	}

	return c.JSON(http.StatusOK, payload)
}

Result:

=== RUN   TestExample
2020/10/27 10:53:59 en
    test_test.go:31: {"error":{"message":"binding element must be a struct"}}
        
--- FAIL: TestExample (0.00s)
FAIL

Process finished with exit code 1

@lammel could you have a look?

@aldas
Copy link
Contributor

aldas commented Oct 29, 2020

@elissa2333 could you reopen this issue?

@lammel
Copy link
Contributor

lammel commented Oct 29, 2020

I think there is a similar issue open concering struct binding.

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

4 participants