Go gin проверяет входные данные, чтобы исключить подстроку

#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]