Search code examples
.netangularjsfluentvalidation

How to get the input errors from asp.net web app into my Index.cshtml view using fluent validation?


I am working on a web form that needs to do a validation for the input fields. I already made that possible with AngularJS(the app uses AngularJS too), but now I need to get those error input messages with ASP.NET more specifically using Fluent Validation. Now I get the results as JSON like Key: CompanyName Message: "Error message appear", but I need it in a format CompanyName: Error message appear. 2nd step is the message to be printed by the input field in HTML. Please if anyone can help me I would really appreciate it. Thank you in advance.

My UserValidator File, containing the Fluent Validation

public class UserValidator : AbstractValidator<UserViewModel>
    {
        public UserValidator()
        {
            RuleFor(p => p.CompanyName)
                .NotNull().WithMessage("This field is required")
                .Length(2, 30).WithMessage("Please enter a valid name!");

            RuleFor(p => p.Name)
                .NotNull().WithMessage("This field is required")
                .Length(2, 30).WithMessage("Please enter a valid name!");


            RuleFor(p => p.Surname)
                .NotNull().WithMessage("This field is required")
                .Length(2, 30).WithMessage("Please enter a valid name!");


            RuleFor(p => p.Phone)
                .NotNull().WithMessage("This field is required")
                .Length(5, 20).WithMessage("No less than 5 numbers, and no more than 20");

            RuleFor(p => p.EMail)
                .EmailAddress().WithMessage("Please enter valid Email address")
                .NotNull().WithMessage("This field is required");

            RuleFor(p => p.Country)
           .NotNull().WithMessage("Please select a country");
        }
       

    }

Now this is the code for my View Model

namespace ViewModel
{
    [Serializable]
    [Validator(typeof (UserValidator))]

    public class UserViewModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Surname { get; set; }
        public string CompanyName { get; set; }
        public string Phone { get; set; }
        public string Country { get; set; }
        public string EMail { get; set; }
        public string Note { get; set; }
    }
}

This is my AppService file containing all the logic:

 public bool Register(UserViewModel model)
        {

            var validator = new UserValidator();
            ValidationResult results = validator.Validate(model);

            if (!results.IsValid)
            {
                var errors = results.Errors
                    .Select(x => new ValidationRecord(x.PropertyName, x.ErrorMessage)).ToList();

                throw new CustomException(errors);

}

return true;
}

Here is my ValidationRecord and CustomValidationException.

    public class ValidationRecord
    {
        public ValidationRecord()
        {

        }
        public ValidationRecord(string key, string message)
        {
            Key = key;
            Message = message;
        }

        public string Key { get; }
        public string Message { get; }
    }
    public class CustomValidationException : Exception
    {
        public CustomValidationException()
            : base()
        {
        }

        public CustomValidationException(string message, params object[] args)
            : base(string.Format(message ?? string.Empty, args))
        {
        }

    }
    public class CustomException : Exception
    {
        public List<ValidationRecord> Errors { get; set; }

        public CustomException()
            : base()
        {
        }

        public CustomException(List<ValidationRecord> errors)
        {
            Errors = errors;
        }
    }
}

My Home Ctrl:

[HttpPost]
public JsonResult Register(UserViewModel model)
        {
            return ActionWrapper.InvokeControlledAction<JsonResult>(x =>
            {
                return Json(_countryService.Register(model));
            });
        }

And now my app.js file:

app.factory('contactFormService', ['$http', function ($http) {
    var dataFactory = {};

    dataFactory.register = function (model) {
        return $http.post("Home/Register/", {model: model});
    };
    return dataFactory;

}]);

app.controller("MainCtrl", ['$scope', '$http', 'contactFormService', function ($scope, $http, contactFormService) {

    $scope.initModel = function () {
        $scope.model = {
            CompanyName: '',
            Name: '',
            Surname: '',
            Phone: '',
            Note: '',
            Country: '',
            EMail: '',
            Errors: []
        };
        $scope.countries = [];
        $scope.showResult = false
    };
    $scope.initModel();


    

    $scope.submitForm = function () {
        contactFormService.register($scope.model)
            .then(function (response) {
                $scope.showResult = true;
            }, function (error) {
                    $scope.model.Errors = error.data
            });

Solution

  • I managed to answer my own question so this code is for everyone that are going to have this problem in the future. The problem mainly was the function I had it wrong. This is the function making assumption that you store your error Validation Messages into an array. Here is the code hope it will be useful for someone.

    $scope.eMessages = function (data) {
            data.ValidationErrors = {};
            angular.forEach(data.Errors, function (key, value) {
                if (key.Key != null) {
                    data.ValidationErrors[key.Key] = key.Message;
                }
           
            });
            return data;
        };