A. Gladkiy
A. Gladkiy

Reputation: 3450

Validation of nested class properties in c#

I have the following class:

public class Container
{
    public ContainerDetails Details { get; set; }

    public class ContainerDetails
    {
        [MaxLength(50)]
        public string Name { get; set; }
    }
}

on controller I have:

public async Task<IActionResult> Details([FromBody] Container model)
{
    if (!ModelState.IsValid)
    {
        throw new Error();
    }
    ...
    return Json();
}

and my ModelState.IsValid always true

Can I validate nested class properties without any custom code? And how? Or may be plugin where I can set some attribute to validate it?

Upvotes: 3

Views: 1563

Answers (2)

paw3lx
paw3lx

Reputation: 56

I think your code is ok. Are you sure you add services.AddMvc() to your Startup.cs file?

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
}

Upvotes: 1

Michael
Michael

Reputation: 2113

Don't know .NET-Core but I think this should work. But you have to roll you own validation stuff and perform recursive calls for each property that has no attribute to validate nested objects.
You should also add additional attributes to mark properties that should not be validated to improve performance of nested validation.

public class MaxLengthAttribute: Attribute
{
    public int Length { get; private set; }
    public MaxLengthAttribute(int length)
    {
        Length = length;
    }
}

public class MyData
{
    [MaxLengthAttribute(5)]
    public string Test { get; set; }
}

public static class Validator
{
    public static void Validate(object o)
    {
        // Returns all public properties of the passed object
        var props = o.GetType().GetProperties();
        foreach(var p in props)
        {
            // Check if this current property has the attribute...
            var attrs = p.GetCustomAttributes(typeof(MaxLengthAttribute), false);
            // Recursive call here if you want to validate nested properties
            if (attrs.Length == 0) continue;

            // Get the attribute and its value
            var attr = (MaxLengthAttribute)attrs[0];
            var length = attr.Length;

            // Get the value of the property that has the attribute
            var current = (string)p.GetValue(o, null);

            // perform the validation
            if (current.Length > length)
                throw new Exception();
        }
    }
}

Upvotes: 0

Related Questions