none
Virtual e Override em asp.net mvc RRS feed

  • Pergunta

  • Olá pessoal.

    Estou com dificuldade no seguinte. Quando um classe herda de outra e transforma uma variavel obrigatoria eu faço o seguinte:

    [DisplayName("Teste")]
    public virtual string x {get;set;}

    e a classe que herda

    [DisplayName("Teste")]
    [Required("Aviso")]
    public override string x {get;set;} 

    isso dá certo... mas eu queria o contrario... fazer de uma variavel obrigatória em outra classe como não obrigatória.

    Obrigado desde já.

    sexta-feira, 27 de maio de 2011 17:11

Respostas

  • Olá ThaleSO,

    Se numa classe base, um determinado atributo é obrigatório e numa classe derivada desta base ele deixa de ser obrigatório, conceitualmente, tens aí um problema no modelo.

    Provavelmente a herança não deveria acontecer diretamente, e a solução mais adequada seria ter uma classe base onde esse atributo não é obrigatório, e então ter duas classes derivadas desta, uma onde o atributo é obrigatório (adiciona), e outra onde o atributo continua como é na base (opcional).

    Algo como:

    public class ClasseBaseViewModel
    {
      [DisplayName("Nome")]
      public virtual string Nome { get; set; }
    
      // ...
    }
    
    public class ClasseDerivada1ViewModel : ClasseBaseViewModel
    {
      [Required(ErrorMessage = "Obrigatorio")]
      public override string Nome { get; set; }
    
      // ...
    }
    
    public class ClasseDerivada2ViewModel : ClasseBaseViewModel
    {
      // ...
    }
    
    

    ---

    No entanto, para fazer exatamente o que você quer, existe um alternativa (que eu não recomendo, mas é possível): Basta criar o seu próprio atributo derivado da classe RequiredAttribute, e então criar uma propriedade para poder indicar que o campo deve deixar de ser obrigatório.

    Algo mais ou menos assim:

    public class SpecialRequiredAttribute : RequiredAttribute
    {
      public bool CancelInheritedRequired { get; set; }
    
      public override bool IsValid(object value)
      {
        return CancelInheritedRequired || base.IsValid(value);
      }
    }
    
    

    E depois, ao invés de utilizar o Required, utilizaria a sua classe - que aqui no exemplo eu chamei de "SpecialRequired":

    public class ClasseBaseViewModel
    {
      [DisplayName("Nome")]
      [SpecialRequired(ErrorMessage = "Obrigatorio")]
      public virtual string Nome { get; set; }
    }
    
    public class ClasseDerivadaViewModel : ClasseBaseViewModel
    {
      [SpecialRequired(CancelInheritedRequired = true)]
      public override string Nome { get; set; }
    }
    
    


    Abraços,

    Caio Proiete
    http://caioproiete.net
    http://twitter.com/CaioProiete

    domingo, 29 de maio de 2011 20:13
    Moderador

Todas as Respostas

  • Olá ThaleSO,

    Se numa classe base, um determinado atributo é obrigatório e numa classe derivada desta base ele deixa de ser obrigatório, conceitualmente, tens aí um problema no modelo.

    Provavelmente a herança não deveria acontecer diretamente, e a solução mais adequada seria ter uma classe base onde esse atributo não é obrigatório, e então ter duas classes derivadas desta, uma onde o atributo é obrigatório (adiciona), e outra onde o atributo continua como é na base (opcional).

    Algo como:

    public class ClasseBaseViewModel
    {
      [DisplayName("Nome")]
      public virtual string Nome { get; set; }
    
      // ...
    }
    
    public class ClasseDerivada1ViewModel : ClasseBaseViewModel
    {
      [Required(ErrorMessage = "Obrigatorio")]
      public override string Nome { get; set; }
    
      // ...
    }
    
    public class ClasseDerivada2ViewModel : ClasseBaseViewModel
    {
      // ...
    }
    
    

    ---

    No entanto, para fazer exatamente o que você quer, existe um alternativa (que eu não recomendo, mas é possível): Basta criar o seu próprio atributo derivado da classe RequiredAttribute, e então criar uma propriedade para poder indicar que o campo deve deixar de ser obrigatório.

    Algo mais ou menos assim:

    public class SpecialRequiredAttribute : RequiredAttribute
    {
      public bool CancelInheritedRequired { get; set; }
    
      public override bool IsValid(object value)
      {
        return CancelInheritedRequired || base.IsValid(value);
      }
    }
    
    

    E depois, ao invés de utilizar o Required, utilizaria a sua classe - que aqui no exemplo eu chamei de "SpecialRequired":

    public class ClasseBaseViewModel
    {
      [DisplayName("Nome")]
      [SpecialRequired(ErrorMessage = "Obrigatorio")]
      public virtual string Nome { get; set; }
    }
    
    public class ClasseDerivadaViewModel : ClasseBaseViewModel
    {
      [SpecialRequired(CancelInheritedRequired = true)]
      public override string Nome { get; set; }
    }
    
    


    Abraços,

    Caio Proiete
    http://caioproiete.net
    http://twitter.com/CaioProiete

    domingo, 29 de maio de 2011 20:13
    Moderador
  • Poxa... muito obrigado pela atenção.
    Eu fiz da maneira que você me recomendou, eu tinha feito isso mas achei que existia uma maneira de implementar menos código. hehe

    Valeu mesmo amigo.  

    segunda-feira, 30 de maio de 2011 12:01