0
votes

I develop a project with Durandal/Breeze/Knockout. Right now, I need to validate an input field on my view with a regular expression.

My first attempt was to insert a data annotation server side on my Entity Framework model like this:

public class Transport
{
    [Key]
    public int Id { get; set; }
    [Required, RegularExpression(@"^\d{2}\.\d{3}$")]
    public string AffairNumber { get; set; }
    ...

Then client side, I have a function for parsing these annotations and insert validation like this:

var addValidationRules = function(entity) {

    var entityType = entity.entityType;

    if (entityType) {
        for (var i = 0; i < entityType.dataProperties.length; i++) {
            var property = entityType.dataProperties[i];
            var propertyName = property.name;
            var propertyObject = entity[propertyName];

            var validators = [];
            for (var u = 0; u < property.validators.length; u++) {
                var validator = property.validators[u];
                var nValidator = {
                    propertyName: propertyName,
                    validator: function (val, other) {
                        var error = this.innerValidator.validate(val, { displayName: this.propertyName });
                        this.message = error ? error.errorMessage : "";
                        return error === null;
                    },
                    message: "",
                    innerValidator: validator
                };
                validators.push(nValidator);
            }
            propertyObject.extend({
                validation: validators
            });
        }

        for (var i = 0; i < entityType.foreignKeyProperties.length; i++) {
            var property = entityType.foreignKeyProperties[i];
            var propertyName = property.name;
            var propertyObject = entity[propertyName];

            var validators = [];
            for (var u = 0; u < property.validators.length; u++) {
                var validator = property.validators[u];
                var nValidator = {
                    propertyName: propertyName,
                    validator: function (val, other) {
                        var error = this.innerValidator.validate(val, { displayName: this.propertyName });
                        this.message = error ? error.errorMessage : "";
                        return error === null;
                    },
                    message: "",
                    innerValidator: validator
                };
                validators.push(nValidator);
            }
            propertyObject.extend({
                validation: validators
            });
            if (!property.isNullable) {
                //Bussiness Rule: 0 is not allowed for required foreign keys
                propertyObject.extend({ notEqual: 0 });
            }
        }
    }
    log('Validation rules added', entity, false);
};

This function is called for each entities I would like to validate like this:

function transportInitializer(transport) {
    addValidationRules(transport);
};

This solution only works for basic validation like Required but for a regular expression validation it doesn't work.

My actual solution was to 'extend' my observable property affairNumber with a pattern like this:

transport.affairNumber.extend({
    pattern: {
        message: 'The affair number must be correctly formatted',
        params: '^\\d{2}\\.\\d{3}$'
    }
});

So when an incorrect value is typed in my input the validation failed. I am note quite satisfied with this solution because I prefer set my validation on my Entity Framework model (server side) rather than duplicating validation on client side.

My question: does Breeze allows me to validate my regular expression retrieved server side? Is there another option I ignore?

Thanks.

1

1 Answers

0
votes

Breeze does not propagate the [RegularExpression] data annotation validation to the client today . That is an oversight. I've noted it internally before. Time to give it your voice by voting for it on User Voice