0

我正在验证从请求发出的参数,但与在 JSON 中发出请求时不同,我无法轻松地将查询参数转换为它的结构对应项。使用以下内容:

https://thedevsaddam.medium.com/an-easy-way-to-validate-go-request-c15182fd11b1

type ItemsRequest struct {
    Item         string `json:"item"`
}
func ValidateItemRequest(r *http.Request, w http.ResponseWriter) map[string]interface{} {
    var itemRequest ItemsRequest
    rules := govalidator.MapData{
        "item":        []string{"numeric"},
    }

    opts := govalidator.Options{
        Request:         r,    
        Rules:           rules,
        Data:            &itemRequest ,
        RequiredDefault: true,
    }
    v := govalidator.New(opts)
    
    e := v.Validate()
    // access itemsRequest.item

}

如果我使用e.ValidateJSON()并通过正文传递数据,则此方法有效

如果我e.Validate()通过 url 参数使用和传递数据,这不起作用。

我认为json结构中的标签是问题,但删除它会产生相同的结果。我不认为 Validate() 应该填充结构,但是我应该如何传递 URL 的值?

我知道我可以r.URL.Query().Get()用来手动提取每个值,但是在我验证了我想要的所有内容之后,这似乎是超级多余的。

4

2 回答 2

1

https://pkg.go.dev/github.com/gorilla/schema可以为您完成繁重的工作,转换url.Values为 astruct并进行一些模式验证。

它支持结构字段标签,非常类似于 - 并且兼容 - json,并且还可以与例如表单数据或多部分表单数据一起使用。

package main

import(
   "github.com/gorilla/schema"
   "net/url"
   "fmt"
)


type Person struct {
    Name  string
    Phone string
}

func main() {
    var decoder = schema.NewDecoder()
    u, err := url.Parse("http://localhost/?name=daniel&phone=612-555-4321")
    if err != nil { panic(err) }
    var person Person
    err = decoder.Decode(&person, u.Query())
    if err != nil {
        // Handle error
    }
    fmt.Printf("%+v\n", person)
}
于 2021-11-06T17:07:28.100 回答
0

首先使用查询中的值填充结构,然后对其进行验证:

q:=request.URL.Query()
myStruct:= {
   Field1: q.Get("field1"),
   Field2: q.Get("field2"),
  ...
}
// Deal with non-string fields

// Validate the struct
于 2021-11-06T16:17:26.037 回答