#validation #go #go-gin
# #проверка #Вперед #go-gin
Вопрос:
Я хочу убедиться, что входные данные не содержат подстрок «организация», «запрещено» и не равны «foo» и «bar».
// cmd/httpd/handler/item_post.go
package handler
import (
"net/http"
"dummy-project/itemdata"
"github.com/gin-gonic/gin"
)
func ItemPost() gin.HandlerFunc {
return func(c *gin.Context) {
requestBody := itemdata.Item{}
if err := c.ShouldBindJSON(amp;requestBody); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"message": err.Error()})
return
}
// insert Item object to DB
c.JSON(http.StatusCreated, requestBody)
}
}
Ниже приведена структура, которую я использовал для запроса POST и вставки записи DB:
// itemdata/item_data.go
пакет itemdata
// Item struct used for POST request and inserting new item
type Item struct {
ID string `bson:"_id" json:"id"`
Name string `bson:"name" json:"name" binding:"required,excludesrune=organizationforbidden,ne=foo,ne=bar"`
}
Когда я вставляю эти значения:
foo -> ошибка проверки при исключении руны
ошибка проверки bar -> на ne
организация -> ошибка проверки при исключении руны
сбой orgfor -> проверка при исключении руны
запрещено -> ошибка проверки при исключении руны
ПАНЕЛЬ -> успех
что я хочу: foo -> сбой
панель -> сбой
организация -> сбой
orgfor -> успех, потому что организация и запрещенное слово не являются целыми
запрещено -> сбой
ПАНЕЛЬ -> сбой
как мне добиться этого с помощью go gin и go validator? Спасибо
Ответ №1:
Похоже, вы пытаетесь исключить целую строку, поэтому excludes
проверка была бы более подходящей, чем excludesrune
. «Руна» в Go — это кодовая точка в Юникоде, которую вы, вероятно, больше привыкли называть просто «символом», поэтому ваша проверка в том виде, в котором она написана, вероятно, не соответствует любой строке, содержащей букву o
.
Попробуйте это вместо:
Name string `bson:"name" json:"name" binding:"required,excludes=organization,excludes=forbidden,ne=foo,ne=bar"`
РЕДАКТИРОВАТЬ: как отмечено в комментариях, это не соответствует вашему требованию о запрете версий заблокированных строк с заглавными буквами. Из того, что я могу сказать, вам нужно будет сделать это с помощью пользовательского средства проверки:
func caseInsensitiveExcludes(fl validator.FieldLevel) bool {
lowerValue := strings.ToLower(fl.Field().String())
if strings.Contains(lowerValue, fl.Param()) {
return false
}
return true
}
validate.RegisterValidation("iexcludes", caseInsensitiveExcludes)
Затем попробуйте это определение поля:
Name string `bson:"name" json:"name" binding:"required,iexcludes=organization,iexcludes=forbidden,ne=foo,ne=bar"`
Комментарии:
1. как мне сделать его не чувствительным к регистру? как FOO, BAR, ОРГАНИЗАЦИЯ должна завершиться неудачей, но сейчас она все еще успешна
2. @nanakondor если вы согласны с тем, чтобы разрешать только строки в нижнем регистре (и отклонять все, что содержит символы в верхнем регистре), вы могли бы добавить
lowercase
тег. В противном случае вам понадобится пользовательский валидатор.3. @nanakondor обновил мой ответ примером того, как может выглядеть этот пользовательский валидатор. Я не тестировал его, поэтому могут быть синтаксические ошибки.
4. является ли тег ne также чувствительным к регистру, и я должен выполнить для него пользовательскую проверку?
5. кроме того, можно ли его изменить, чтобы включить все в один снимок? например, iexcludes=[test1, test2, test3]