v9.30
I have a field that is a string, that I want to allow to be null or a string, but not an empty/blank string. I can't find a way to validate this without making the field a pointer, which I can't do because then json umarshalling doesn't run.
NullString is a custom type that is a sql.NullString with a set value so I know whether an explicit NULL was sent from a json request. see: https://www.calhoun.io/how-to-determine-if-a-json-key-has-been-set-to-null-or-not-provided/
type A struct {
Email NullString `json:"email,omitempty", validate:"omitempty,email"
}
type NullString struct {
Set bool
sql.NullString
}
// more methods to this with marshal/scan/value implementations
The issue I run into with this is if I make NullString a pointer, the json unmarshalling doesn't get called, validation works as expected. If I keep NullString as is, it unmarshals correctly, but validation doesn't get called.
There are 3 ways I can see solving this:
omitnil or omitnull that checks for an explicit nil instead of just a zero value. I can't seem to find a way to do this.notempty validator (similar to the non-standard notblank) that checks explicitly for an empty string "". Issue is with this approach is that the validation doesn't seem to run when the value is a Nil or Zero value, even if I pass the callValidationEvenIfNull param on RegisterValdiation ( maybe this is incorrect )validation:eq=null|email or maybe validation:ne=|email ( this may work, just thought of it now, but would prefer not to use this method)I would prefer not to use the 3rd option if possible
@dlpetrie so your validation is on the right track, but since Go's type system requires a pointer to a value eg. *string to indicate the absence of a value is where you're getting tripped up.
for example if your struct was like so, it would work:
type A struct {
Email *string `json:"email,omitempty", validate:"omitempty,email"
}
Since NullString is always present omitempty is essentially ignored right now, what you need to do is register a CustomTypeFunc which allows you to use NullString but return the base nil or a real value in order to have omitempty to work.
There is a fully working example of this within this repo here
let me now if this helps.
Most helpful comment
@dlpetrie so your validation is on the right track, but since Go's type system requires a pointer to a value eg.
*stringto indicate the absence of a value is where you're getting tripped up.for example if your struct was like so, it would work:
Since
NullStringis always presentomitemptyis essentially ignored right now, what you need to do is register aCustomTypeFuncwhich allows you to useNullStringbut return the basenilor a real value in order to haveomitemptyto work.There is a fully working example of this within this repo here
let me now if this helps.