0

What is the correct way to use advance property validation when deserializing JSON to Model? I am providing the MyClass as an example. I need to validate Name(required) and Email(e-mail address validation). I do find only [JsonProperty(Required = Required.Always)] to validate the required properties and nothing for e-mail validation. Unfortunately, Data Annotation validators can't be used from MVC for validation.

One idea which comes to my mind is to create custom ContractResolver and attach to deserializer where I could perform custom validation. Any other methods to consider?

public class MyClass
{
   [JsonProperty(Required = Required.Always)]
   public string Name { get; set; }
   public string Email { get; set; }
}

_dto = JsonConvert.DeserializeObject<MyClass>(content);
Tomas
  • 17,551
  • 43
  • 152
  • 257
  • I haven't tested this yet, but what if you simply use `MainAddress` instead of `string` for your `Email` property? that will give you the validation for free... – Zohar Peled Nov 26 '19 at 11:29
  • @Zohar what is `MainAddress`? – Tomas Nov 26 '19 at 11:31
  • https://learn.microsoft.com/en-us/dotnet/api/system.net.mail.mailaddress?view=netframework-4.8 – Zohar Peled Nov 26 '19 at 11:32
  • @ZoharPeled It is MailAddress, not MainAddres. Also, I don't get how this validates? I will get an exception. Also how to validate Uri property then? It deserializes and binds perfectly with any string and throw Uri malformed exception when accessed. – Tomas Nov 26 '19 at 11:48
  • Sorry, automatically typing Main everywhere... :-) – Zohar Peled Nov 26 '19 at 11:52
  • As I said, I haven't tested this yet. I'll try to find the time to do that later today. – Zohar Peled Nov 26 '19 at 11:56

2 Answers2

1

So I've had some time to test this, and as I suspected, MailAddress is deserialized to a much more complex json object than a simple address - which means that if you want to keep your json as is, you can't change the property type to MailAddress.

However, this doesn't mean you can't take advantage of the built in format validation it has in it's constructor, just not with auto-implemented properties.
If you change your class to this -

public class MyClass
{
    private string email;

   [JsonProperty(Required = Required.Always)]
   public string Name { get; set; }
   [JsonProperty(Required = Required.Always)]
   public string Email { 
       get
       {
           return email;
       }
       set
       {
           var address = new MailAddress(value); 
           email = value;
       }
   }
}

Whenever you try to deserialize a json that contains an invalid format email address (and in fact, whenever you try to set this property to a string that's not a valid email address), you'll get a FormatException:

System.FormatException: The specified string is not in the form required for an e-mail address.

Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
0
public class MyClass
{
   [JsonProperty("name", Required = Required.Always)]
   public string Name { get; set; }

   [JsonProperty("email", Required = Required.Always)]
   public string Email { get; set; }
}

To validate the email you'll have to apply your own regex check after you deserialize.

Paul Brittain
  • 319
  • 2
  • 17
  • Don't use regular expressions to validate an email address. Instead, [use the tools the framework already provides you.](https://stackoverflow.com/questions/58356341/whats-the-best-regex-validation-for-email-address/58411056#58411056) – Zohar Peled Nov 26 '19 at 11:32
  • Sure, he'll have to apply whatever method of email validation after the deserialization anyway. Not that there's anything wrong with regex validation. – Paul Brittain Nov 26 '19 at 11:51