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

error validation for embedded struct #2482

Closed
icehan2016 opened this issue Mar 2, 2023 · 4 comments
Closed

error validation for embedded struct #2482

icehan2016 opened this issue Mar 2, 2023 · 4 comments
Labels
bug It is confirmed a bug, but don't worry, we'll handle it. done This issue is done, which may be release in next version.

Comments

@icehan2016
Copy link

icehan2016 commented Mar 2, 2023

1. What version of Go and system type/arch are you using?

go version go1.20.1 darwin/arm64

2. What version of GoFrame are you using?

GoFrame CLI Tool v2.3.2, https://goframe.org
GoFrame Version: v2.3.2 in current go.mod

4. What did you do?

定义了两个请求结构体 并且嵌套
外层 校验有效
内层 嵌套无效

type CreateOrderReq struct {
	g.Meta       `path:"/order" tags:"订单" method:"put" summary:"创建订单"`
	Type         int           `p:"type" v:"required#请输入订单类型" dc:"类型"`
	Factory_id   int           `p:"factory_id" v:"required#请输入工厂id" dc:"工厂id"`
	Factory_name string        `p:"factory_name" v:"required#请输入工厂名称" dc:"工厂名称"`
	Create_at_at *gtime.Time   `p:"create_at_at" v:"required#请输入创建时间" dc:"创建日期"`
	Pay_status   int           `p:"pay_status" v:"required#请输入付款状态" dc:"付款状态"`
	Details      []*OrderDetail `p:"detail" v:"required#请输入订单详情" dc:"订单详情"`
	Pay_at       *gtime.Time   `p:"pay_at" v:"required#请输入付款状态" dc:"付款日期"`
	Finish_at    *gtime.Time   `p:"finish_at" v:"required#请输入付款状态" dc:"完成日期"`
}
type OrderDetail struct {
	Name   string  `p:"name" v:"required#请输入物料名称" dc:"物料名称"`
	Sn     string  `p:"sn" v:"required#请输入客户编号" dc:"客户编号"`
	Images string  `p:"images" dc:"图片"`
	Desc   string  `p:"desc" dc:"备注"`
	Number int     `p:"number" v:"required#请输入数量" dc:"数量"`
	Price  float64 `p:"price" v:"required" dc:"单价"`
}

func (c *orderController) CreateOrder(ctx context.Context, req *v1.CreateOrderReq) (res *v1.CreateOrderRes, err error) {
	for _, detail := range req.Details {

                //可以接收到数据 但是无法校验数据
		fmt.Println("物料名称:", detail.Name)  
		fmt.Println("物料编号:", detail.Sn)
		fmt.Println("物料图片:", detail.Images)

	}
	return
}

请求数据 detail 中 故意漏掉 name 和 sn 无法校验

{
  "type": 0,
  "factory_id": 0,
  "factory_name": "string",
  "create_at_at": "string",
  "pay_status": 0,
  "detail": [
    {
      "images": "string",
      "desc": "string",
      "number": 0,
      "price": 0
    }
  ],
  "pay_at": "string",
  "finish_at": "string"
}

5. What did you expect to see?

嵌套的内侧 也可以 校验

@gqcn
Copy link
Member

gqcn commented Mar 2, 2023

@icehan2016 请提供可复现该问题的最小可执行代码。

@icehan2016
Copy link
Author

icehan2016 commented Mar 2, 2023

//定义两个结构体用来 接收 请求参数 [api/v1/order.go]

type CreateOrderReq struct {
	g.Meta       `path:"/order" tags:"订单" method:"put" summary:"创建订单"`
	Type         int            `p:"type" v:"required#请输入订单类型" dc:"类型"`
	Factory_id   int            `p:"factory_id" v:"required#请输入工厂id" dc:"工厂id"`
	Factory_name string         `p:"factory_name" v:"required#请输入工厂名称" dc:"工厂名称"`
	Create_at_at *gtime.Time    `p:"create_at_at" v:"required#请输入创建时间" dc:"创建日期"`
	Pay_status   int            `p:"pay_status" v:"required#请输入付款状态" dc:"付款状态"`
	Details      []*OrderDetail `p:"detail" v:"required#请输入订单详情" dc:"订单详情"`
	Pay_at       *gtime.Time    `p:"pay_at" v:"required#请输入付款状态" dc:"付款日期"`
	Finish_at    *gtime.Time    `p:"finish_at" v:"required#请输入付款状态" dc:"完成日期"`
}

type OrderDetail struct {
	Name   string  `p:"name" v:"required#请输入物料名称" dc:"物料名称"`
	Sn     string  `p:"sn" v:"required#请输入客户编号" dc:"客户编号"`
	Images string  `p:"images" dc:"图片"`
	Desc   string  `p:"desc" dc:"备注"`
	Number int     `p:"number" v:"required#请输入数量" dc:"数量"`
	Price  float64 `p:"price" v:"required" dc:"单价"`
}
//定义一个Controller [internal/controller/order.go]

var (
	Order = orderController{}
)

type orderController struct{}

func (c *orderController) CreateOrder(ctx context.Context, req *v1.CreateOrderReq) (res *v1.CreateOrderRes, err error) {
	for _, detail := range req.Details {

		fmt.Println("物料名称:", detail.Name)
		fmt.Println("物料编号:", detail.Sn)
		fmt.Println("物料图片:", detail.Images)

	}
	return
}
//中间件捕获异常 [internal/middleware/middleware.go]
func MiddlewareErrorHandler(r *ghttp.Request) {

	r.Middleware.Next()
	if r.GetError() != nil {
		r.Response.WriteJson(g.Map{
			"code":   100,
			"data":   r.GetError().Error(),
			"status": "error",
		})
	}
}
//路由中 绑定 orderController[internal/router/web.go]
s.Group("/api/v1", func(group *ghttp.RouterGroup) {
          group.Middleware(middleware.MiddlewareErrorHandler)
          group.Bind(
	          controller.Order,
          )

})

postman [put] api/v1/order

请求数据为:

{
  "type": 0,
  "factory_id": 0,
  "factory_name": "string",
  "create_at_at": "string",
  "pay_status": 0,
  "detail": [
    {
      "images": "string",
      "desc": "string",
      "number": 0,
      "price": 0
    }
  ],
  "pay_at": "string",
  "finish_at": "string"
}

因为请求数据中的detail 部分数据缺失
按照逻辑
应该被中间件捕获异常 并且抛出
但是没有被捕获

@gqcn
Copy link
Member

gqcn commented Mar 3, 2023

```go
//定义两个结构体用来 接收 请求参数 [api/v1/order.go]

type CreateOrderReq struct {
	g.Meta       `path:"/order" tags:"订单" method:"put" summary:"创建订单"`
	Type         int            `p:"type" v:"required#请输入订单类型" dc:"类型"`
	Factory_id   int            `p:"factory_id" v:"required#请输入工厂id" dc:"工厂id"`
	Factory_name string         `p:"factory_name" v:"required#请输入工厂名称" dc:"工厂名称"`
	Create_at_at *gtime.Time    `p:"create_at_at" v:"required#请输入创建时间" dc:"创建日期"`
	Pay_status   int            `p:"pay_status" v:"required#请输入付款状态" dc:"付款状态"`
	Details      []*OrderDetail `p:"detail" v:"required#请输入订单详情" dc:"订单详情"`
	Pay_at       *gtime.Time    `p:"pay_at" v:"required#请输入付款状态" dc:"付款日期"`
	Finish_at    *gtime.Time    `p:"finish_at" v:"required#请输入付款状态" dc:"完成日期"`
}

type OrderDetail struct {
	Name   string  `p:"name" v:"required#请输入物料名称" dc:"物料名称"`
	Sn     string  `p:"sn" v:"required#请输入客户编号" dc:"客户编号"`
	Images string  `p:"images" dc:"图片"`
	Desc   string  `p:"desc" dc:"备注"`
	Number int     `p:"number" v:"required#请输入数量" dc:"数量"`
	Price  float64 `p:"price" v:"required" dc:"单价"`
}
//定义一个Controller [internal/controller/order.go]

var (
	Order = orderController{}
)

type orderController struct{}

func (c *orderController) CreateOrder(ctx context.Context, req *v1.CreateOrderReq) (res *v1.CreateOrderRes, err error) {
	for _, detail := range req.Details {

		fmt.Println("物料名称:", detail.Name)
		fmt.Println("物料编号:", detail.Sn)
		fmt.Println("物料图片:", detail.Images)

	}
	return
}
//中间件捕获异常 [internal/middleware/middleware.go]
func MiddlewareErrorHandler(r *ghttp.Request) {

	r.Middleware.Next()
	if r.GetError() != nil {
		r.Response.WriteJson(g.Map{
			"code":   100,
			"data":   r.GetError().Error(),
			"status": "error",
		})
	}
}
//路由中 绑定 orderController[internal/router/web.go]
s.Group("/api/v1", func(group *ghttp.RouterGroup) {
          group.Middleware(middleware.MiddlewareErrorHandler)
          group.Bind(
	          controller.Order,
          )

})

postman [put] api/v1/order
请求数据为:

{
  "type": 0,
  "factory_id": 0,
  "factory_name": "string",
  "create_at_at": "string",
  "pay_status": 0,
  "detail": [
    {
      "images": "string",
      "desc": "string",
      "number": 0,
      "price": 0
    }
  ],
  "pay_at": "string",
  "finish_at": "string"
}

因为请求数据中的detail 部分数据缺失
按照逻辑
应该被中间件捕获异常 并且抛出
但是没有被捕获

你好,你这个拆解后的代码不太好组织,能直接给一个main.go的代码吗?

@icehan2016
Copy link
Author

package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gtime"
)

// 请求结构体
type CreateOrderReq struct {
	g.Meta       `path:"/order" tags:"订单" method:"put" summary:"创建订单"`
	Type         int            `p:"type" v:"required#请输入订单类型" dc:"类型"`
	Factory_id   int            `p:"factory_id" v:"required#请输入工厂id" dc:"工厂id"`
	Factory_name string         `p:"factory_name" v:"required#请输入工厂名称" dc:"工厂名称"`
	Create_at_at *gtime.Time    `p:"create_at_at" v:"required#请输入创建时间" dc:"创建日期"`
	Pay_status   int            `p:"pay_status" v:"required#请输入付款状态" dc:"付款状态"`
	Details      []*OrderDetail `p:"detail" v:"required#请输入订单详情" dc:"订单详情"`
	Pay_at       *gtime.Time    `p:"pay_at" v:"required#请输入付款状态" dc:"付款日期"`
	Finish_at    *gtime.Time    `p:"finish_at" v:"required#请输入付款状态" dc:"完成日期"`
}

type OrderDetail struct {
	Name   string  `p:"name" v:"required#请输入物料名称-1" dc:"物料名称"`
	Sn     string  `p:"sn" v:"required#请输入客户编号" dc:"客户编号"`
	Images string  `p:"images" dc:"图片"`
	Desc   string  `p:"desc" dc:"备注"`
	Number int     `p:"number" v:"required#请输入数量" dc:"数量"`
	Price  float64 `p:"price" v:"required" dc:"单价"`
}

// Controller
type CreateOrderRes struct {
}

var (
	Order = OrderController{}
)

type OrderController struct{}

// Controller function
func (c *OrderController) CreateOrder(ctx context.Context, req *CreateOrderReq) (res *CreateOrderRes, err error) {
	for _, detail := range req.Details {

		fmt.Println("物料名称:", detail.Name)
		fmt.Println("物料编号:", detail.Sn)
		fmt.Println("物料图片:", detail.Images)

	}
	return
}

func MiddlewareErrorHandler(r *ghttp.Request) {

	r.Middleware.Next()

	//校验请求数据
	if r.GetError() != nil {
		r.Response.WriteJson(g.Map{
			"code":   100,
			"data":   r.GetError().Error(),
			"status": "error",
		})
	}
	if r.Response.Status >= http.StatusInternalServerError {
		r.Response.ClearBuffer()
		r.Response.WriteJson(g.Map{
			"code":   100,
			"data":   "服务器开小差了,运维正在重启服务器中",
			"status": "error",
		})
	}

}

func main() {
	s := g.Server()
	s.Group("/api/v2", func(group *ghttp.RouterGroup) {

		group.Middleware(MiddlewareErrorHandler)
		group.Bind(Order)

	})

	s.Run()
}

谢谢!

@gqcn gqcn changed the title 请求校验 无法校验内层结构体 error validation for embedded struct Mar 7, 2023
@gqcn gqcn added the bug It is confirmed a bug, but don't worry, we'll handle it. label Jul 20, 2023
gqcn added a commit that referenced this issue Jul 20, 2023
@gqcn gqcn added the done This issue is done, which may be release in next version. label Jul 20, 2023
@gqcn gqcn closed this as completed Jul 20, 2023
gqcn added a commit that referenced this issue Jul 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug It is confirmed a bug, but don't worry, we'll handle it. done This issue is done, which may be release in next version.
Projects
None yet
Development

No branches or pull requests

2 participants