dpqg86714 2018-05-25 06:50
浏览 444

如果Gin验证失败,如何返回自定义错误

For example I've got the following struct

type Address struct {
    City string `json:"city" binding:"required"`
    AddressLine string `json:"address_line" binding:"required"`
}

and I've got the following function to handle request from users

func AddressCreate(c *gin.Context) {
    var address Address
    if err := c.BindJSON(&address); err == nil {
        // if everything is good save to database
        // and return success message
        db.Create(&address)
        c.JSON(http.StatusOK, gin.H {"status":"success"})
    } else {
        c.JSON(http.StatusBadRequest, err)
    }
}

Expected behavior is to return json formatted this way

[
     {
         "city":"required"
     }
     {
         "address_line":"required"
     }
]

But I'm getting error formatted like this

"Address.City": {
    "FieldNamespace": "Address.City",
    "NameNamespace": "City",
    "Field": "City",
    "Name": "City",
    "Tag": "required",
    "ActualTag": "required",
    "Kind": 24,
    "Type": {},
    "Param": "",
    "Value": ""
},
"Address.AddressLine": {
    "FieldNamespace": "AddressLine",
    "NameNamespace": "AddressLine",
    "Field": "AddressLine",
    "Name": "AddressLine",
    "Tag": "required",
    "ActualTag": "required",
    "Kind": 24,
    "Type": {},
    "Param": "",
    "Value": ""
}

What did I tried:
I created function which casts error to ValidationErrors and iterates through all FieldError's in it

func ListOfErrors(e error) []map[string]string {
    ve := e.(validator.ValidationErrors)
    InvalidFields := make([]map[string]string, 0)

    for _, e := range ve {
        errors := map[string]string{}
        // field := reflect.TypeOf(e.NameNamespace)
        errors[e.Name] = e.Tag
        InvalidFields = append(InvalidFields, errors)
    }

    return InvalidFields
}

The output look's much better

[
    {
        "City":"required"
    },
    {
        "AddressLine":"required"
    }
]

But I cannot solve the problem with the name of the fields. I cannot swap Name into name which I noted in structs tag json:"city". So my question is did I choose correct way to solve the problem if the answer is yes how to get structs json tag for field?

  • 写回答

2条回答 默认 最新

  • dounanyin3179 2018-05-25 07:27
    关注

    You can use ToSnake to snake case the names:

    import (
        "unicode"
    )
    
    // ToSnake convert the given string to snake case following the Golang format:
    // acronyms are converted to lower-case and preceded by an underscore.
    func ToSnake(in string) string {
        runes := []rune(in)
        length := len(runes)
    
        var out []rune
        for i := 0; i < length; i++ {
            if i > 0 && unicode.IsUpper(runes[i]) && ((i+1 < length && unicode.IsLower(runes[i+1])) || unicode.IsLower(runes[i-1])) {
                out = append(out, '_')
            }
            out = append(out, unicode.ToLower(runes[i]))
        }
    
        return string(out)
    }
    
    
    
    func ListOfErrors(e error) []map[string]string {
        ve := e.(validator.ValidationErrors)
        invalidFields := make([]map[string]string, 0)
    
        for _, e := range ve {
            errors := map[string]string{}
            errors[ToSnake(e.Name)] = e.Tag
            invalidFields = append(InvalidFields, errors)
        }
    
        return invalidFields
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探