Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Data Annotations attributes from model

I want to create custom client-side validator, but I want define validation rules via Data Annotations attributes at business logic layer. How can I access model validation attributes in runtime?

I want to write 'generator', which will convert this code:

public class LoginModel
{
    [Required]
    [MinLength(3)]
    public string UserName { get; set; }

    [Required]
    public string Password { get; set; }
}

into this one:

var loginViewModel= {
    UserName: ko.observable().extend({ minLength: 3, required: true }),
    Password: ko.observable().extend({ required: true })
};

But not from .cs sources, of course. =)

Maybe reflection?

UPD

I've found this method: MSDN. But can't understand how to use it.

like image 316
letalumil Avatar asked Oct 28 '13 14:10

letalumil


People also ask

What is data annotation validator attributes in MVC?

Data annotation attributes are attached to the properties of the model class and enforce some validation criteria. They are capable of performing validation on the server side as well as on the client side. This article discusses the basics of using these attributes in an ASP.NET MVC application.

What is data annotation attribute?

Data Annotations attributes are . NET attributes which can be applied on an entity class or properties to override default conventions in EF 6 and EF Core. Data annotation attributes are included in the System. ComponentModel.

Can we do validation in MVC using data annotations?

In ASP.NET MVC, Data Annotation is used for data validation for developing web-based applications. We can quickly apply validation with the help of data annotation attribute classes over model classes.


1 Answers

This is the universal way how to do this:

private string GenerateValidationModel<T>()
{
    var name = typeof(T).Name.Replace("Model", "ViewModel");
    name = Char.ToLowerInvariant(name[0]) + name.Substring(1);

    var validationModel = "var " + name + " = {\n";

    foreach (var prop in typeof(T).GetProperties())
    {
        object[] attrs = prop.GetCustomAttributes(true);
        if (attrs == null || attrs.Length == 0)
            continue;

        string conds = "";

        foreach (Attribute attr in attrs)
        {
            if (attr is MinLengthAttribute)
            {
                conds += ", minLength: " + (attr as MinLengthAttribute).Length;
            }
            else if (attr is RequiredAttribute)
            {
                conds += ", required: true";
            }
            // ...
        }

        if (conds.Length > 0)
            validationModel += String.Format("\t{0}: ko.observable().extend({{ {1} }}),\n", prop.Name, conds.Trim(',', ' '));
    }

    return validationModel + "};";
}

Usage:

string validationModel = GenerateValidationModel<LoginModel>();

Output:

var loginViewModel = {
    UserName: ko.observable().extend({ minLength: 3, required: true}),
    Password: ko.observable().extend({ required: true}),
};

It's good idea to cache the output

like image 177
Damian Drygiel Avatar answered Sep 23 '22 22:09

Damian Drygiel