Validation using Remote in the "Parent" class

Asked

Viewed 414 times

2

I have my class Person, it owns the property CPF

public class Pessoa {
   public string Cpf {get;set;}
}

Other classes inherit from it, for example, the Client class

public class Cliente : Pessoa {
}

Turns out I use the Data Annotation Remote

[Remote("CheckCpf", "Validation", AdditionalFields = "Id", ErrorMessage = "Mensagem.")]

How can I use the Remote validating in each class it inherits from Person ?

For example: Client:

 [Remote("CheckCpfCLIENTE", "Validation", AdditionalFields = "Id", ErrorMessage = "Mensagem.")]

Supplier:

 [Remote("CheckCpfFornecedor", "Validation", AdditionalFields = "Id", ErrorMessage = "Mensagem.")]

3 answers

1

One way to do this is by searching directly with ADO.Net but I advise using a ORM. Are you working with any ORM? Nhibernate or EF.

If you inform me that I try to show you how to do it. Send me your remote validation code as well.

Take a look also at my blog. I did a post there that answered a question here about remote validation. Remember to always validate the ID also because if you do not do this you will have problems to change your objects as it will appear that already exists in the BD.

There you can download a project in Asp net mvc 5 with remote validation working as well. http://blogdoquintal.net/2015/01/06/fazendo-validacao-ajax-no-servidor-com-asp-net-mvc/

  • Hello @Marco, my problem is not validation, but inheritance of properties

  • So do what the Gypsy downstairs said.

  • it doesn’t make sense that, I’ll see what I do

1


Remote supposes that the validation is in Controller, not in the Model.

According to your question, you own a ValidationController which has the validation method, which is correct if the intention is to validate by Javascript. If the intention is to validate by actually persisting the record, it is necessary to implement a CPF attribute that validates the Model.

An example of a CPF validation attribute of the type string is below, considering points and traits:

using System;
using System.ComponentModel.DataAnnotations;
using SeuProjeto.Models;

namespace SeuProjeto.Attributes
{
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
    sealed public class CpfAttribute : ValidationAttribute
    {
        private MaxiMailContext context = new MaxiMailContext();

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value == null) return null;

            int soma = 0, resto = 0;
            string digito;
            int[] multiplicador1 = new int[9] { 10, 9, 8, 7, 6, 5, 4, 3, 2 };
            int[] multiplicador2 = new int[10] { 11, 10, 9, 8, 7, 6, 5, 4, 3, 2 };

            string CPF = value.ToString().Replace(".", "").Replace("-", "");

            if (CPF.Length != 11)
                return new ValidationResult("CPF Inválido.");

            if (Convert.ToUInt64(CPF) % 11111111111 == 0)
                return new ValidationResult("CPF Inválido.");

            decimal CPFDecimal = Convert.ToDecimal(CPF);


            /* if (validationContext.ObjectInstance.GetType() == typeof(Customer))
            {
                var model = (Customer)validationContext.ObjectInstance;

                if (context.Customers.Any(c => (c.CPF == CPFDecimal) && (c.CustomerId != model.CustomerId)))
                {
                    var message = FormatErrorMessage("CPF já está cadastrado em outra conta de cliente.");
                    return new ValidationResult(message);
                }
            }
            else
            {
                if (context.Customers.Any(c => (c.CPF == CPFDecimal)))
                {
                    var message = FormatErrorMessage("CPF já está cadastrado em outra conta de cliente.");
                    return new ValidationResult(message);
                }
            } */

            string tempCpf = CPF.Substring(0, 9);

            for (int i = 0; i < 9; i++)
                soma += int.Parse(tempCpf[i].ToString()) * multiplicador1[i];

            resto = soma % 11;
            if (resto < 2)
                resto = 0;
            else
                resto = 11 - resto;

            digito = resto.ToString();
            tempCpf = tempCpf + digito;
            soma = 0;

            for (int i = 0; i < 10; i++)
                soma += int.Parse(tempCpf[i].ToString()) * multiplicador2[i];

            resto = soma % 11;

            if (resto < 2)
                resto = 0;
            else
                resto = 11 - resto;

            digito = digito + resto.ToString();

            if (CPF.EndsWith(digito))
                return null;
            else
                return new ValidationResult("CPF Inválido.");
        }

        public override string FormatErrorMessage(string name)
        {
            return name;
        }
    }
}
  • the validation code is done in the "Validation" controller, my problem is that in the Checkcpf action, I pass in my db.Cliente.Where(x => x.Cpf == Cpf.. if it is supplier or something... but as I have the CPF in Person, how will I do it ?

  • @Rod If CPF exists in the Model Pessoa, is in it that you will check. If every Model has its CPF field, it is necessary to make a different method for each Controller.

  • I’ll answer what I did here, at first it worked...

  • @Rod I updated the answer.

  • take a look at the answer I published

1

Like all classes that inherit from person, also has the CPF property, I did it as follows:

In the Person class I leave my CPF property as virtual

public virtual string CPF {get;set;}

In my Client class for example, I override the person CPF property:

    [Remote("CheckCpfCliente", "Cliente", AdditionalFields = "Id", ErrorMessage = "Mensagem erro")]
    public override string CPF
    {
        get
        {
            return base.CnpjCpf;
        }
        set
        {
            base.CnpjCpf = value;
        }
    }

and do the same thing in other classes that inherit from Pessoa, just changing the "Action" and "Controller" from the remote

  [Remote("CheckCpfFORNECEDOR, "FORNECEDOR")
  [Remote("CheckCpfFUNCIONARIO, "FUNCIONARIO")

etc.

  • In fact this only proves a design hole of ASP.NET MVC itself, where you need to necessarily define a different validation method for each entity derived from Pessoa. The gain of your application with this is close to none.

  • @Ciganomorrisonmendez because it is, your validation that you posted, through an attribute, is only on the server right? I would like to use Remote because it still validate in the client

  • You just adapt the attribute so it becomes a method of Controller.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.