1

With an attribute [JsonProperty(Required = Required.Always)] annotating my model I am able to check, that the property value is not null.

For strings I would like to check for empty values as well. Is there a way to check if string property value is empty while using attributes in Json.NET? Or is there any other way?

This JSON should cause a problem

{
  "Property1": "",
   ... 
}
1
  • Looks like you'll have to use JSON Schema to validate that. Commented Mar 1, 2019 at 18:30

1 Answer 1

5

By using a JSON schema you can define minimum lengths for specific properties, among other things. This is reasonably simple using the additional Json.NET Schema package, after slight modifications to the deserialization code to specify the schema to be used for validation. However, the Json.NET Schema library is not MIT licensed and uses restrictive/commercial licensing unlike Json.NET itself. There may be other implementations, though.

In a similar case I ended up (ab)using a JsonConverter to do validation instead. This is somewhat hacky as it's not really a converter, but the convenient thing is that it works purely by applying a Json.NET attribute to the model without any other code changes.

public class NonEmptyStringConverter : JsonConverter
{
    public override bool CanConvert(Type objectType) => objectType == typeof(string);

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        => throw new NotImplementedException();

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType != JsonToken.String)
            throw CreateException($"Expected string value, but found {reader.TokenType}.", reader);

        var value = (string)reader.Value;

        if (String.IsNullOrEmpty(value))
            throw CreateException("Non-empty string required.", reader);

        return value;
    }

    private static Exception CreateException(string message, JsonReader reader)
    {
        var info = (IJsonLineInfo)reader;
        return new JsonSerializationException(
            $"{message} Path '{reader.Path}', line {info.LineNumber}, position {info.LinePosition}.",
            reader.Path, info.LineNumber, info.LinePosition, null);
    }
}

Usage:

[JsonProperty(Required = Required.Always)]
[JsonConverter(typeof(NonEmptyStringConverter))]
public string Property1 { get; set; }

The Required.Always should still be applied to handle cases where the property is missing completely, in which case the converter won't be called by Json.NET.

Sign up to request clarification or add additional context in comments.

2 Comments

Just checking if anything changed since 3/2019? no built in attribute?
anything changed a few years later? still have this issue today

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.