Jan 31

Validando Dados com EntityFramework e WindowsForms

Pessoal,

Hoje vou mostrar uma maneira bem simples e interessante de fazer validação de dados com EntityFramework, classes POCO e uma aplicação Windows Forms.

Como eu já comentei em outros posts, quando você utiliza DataAnnotations em classes POCO na sua camada de dados e faz a camada de apresentação com WPF/Silverlight ou MVC, o tratamento dos campos é feito automaticamente, praticamente sem nenhum tipo de código. Mas e se você ainda programa para WindowsForms ou precisa validar os dados da classe em uma camada e retornar o erro para outra camada, como fazer ? Isto é o que veremos a seguir.

Primeiro vamos criar um projeto Windows Forms no Visual Studio 2010:
image

Agora vamos adicionoar o EntityFramework CodeFirst usando o NuGet, como eu expliquei neste post. E logo após vamos criar uma classes chamada Produto e vamos adicionar os annotations nela. Annotations são marcações acima dos campos que definem várias informações ao engine do Entitu Framework, como por exemplo, os valores permitidos no campo.

Nossa classe produto ficará da seguinte maneira:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using System.ComponentModel.DataAnnotations;
  6:
  7: namespace WindowsFormsValidacao
  8: {
  9:     [Table("Produto")]
 10:     public class Produto : ValidacaoEntidade
 11:     {
 12:         public int ID { get; set; }
 13:         [Required(ErrorMessage="Descrição em branco"])
 14:         public string Descricao { get; set; }
 15:         [Range(1,10000,ErrorMessage="Valor deve estar entre 1 e 10000")]
 16:         public double SaldoMinimo { get; set; }
 17:         [Required(ErrorMessage="Custo em branco")]
 18:         public decimal Custo { get; set; }
 19:         public decimal Venda { get; set; }
 20:         [MaxLength(20,ErrorMessage="Tamanho máximo = 20")]
 21:         public string Localizacao { get; set; }
 22:     }
 23: }

Veja que a nossa classe está herdando de ValidacaoEntidade, que é onde iremos fazer o método de validaçao dos campos, veja abaixo:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using System.ComponentModel;
  6: using System.ComponentModel.DataAnnotations;
  7: using System.Xml.Serialization;
  8:
  9: namespace WindowsFormsValidacao
 10: {
 11:     public class ValidacaoEntidade : IDataErrorInfo
 12:     {
 13:         [NotMapped]
 14:         public string Error
 15:         {
 16:             get { return ""; }
 17:         }
 18:
 19:         [NotMapped]
 20:         public string this[string columnName]
 21:         {
 22:             get
 23:             {
 24:                 return ValidateProperty(columnName);
 25:             }
 26:         }
 27:
 28:         protected string ValidateProperty(string propertyName)
 29:         {
 30:             var info = this.GetType().GetProperty(propertyName);
 31:
 32:             if (!info.CanWrite)
 33:             {
 34:                 return null;
 35:             }
 36:
 37:             var value = info.GetValue(this, null);
 38:             IEnumerable<string> errorInfos =
 39:                   (from va in info.GetCustomAttributes(true).OfType<ValidationAttribute>()
 40:                    where !va.IsValid(value)
 41:                    select va.FormatErrorMessage(string.Empty)).ToList();
 42:
 43:
 44:             if (errorInfos.Count() > 0)
 45:             {
 46:                 return errorInfos.FirstOrDefault<string>();
 47:             }
 48:             return null;
 49:         }
 50:
 51:         public IEnumerable<string> Validate(bool Formatar=false)
 52:         {
 53:             foreach (var prop in this.GetType().GetProperties())
 54:             {
 55:                 string err = ValidateProperty(prop.Name);
 56:                 if (!String.IsNullOrWhiteSpace(err))
 57:                 {
 58:                     yield return prop.Name + ": " + err + ((Formatar) ? "<br>" : "").ToString();
 59:                 }
 60:             }
 61:         }
 62:     }
 63: }

Nesta classe está o segredo da validação, o método Validate(). Este método percorre todos os campos da nossa classe e verifica seu CustomAttribute(), procurando pelo ValidationAttribute, que é o nosso DataAnnotations, se o valor não for for válido, ele retorna a mensagem de erro que atribuímos ao campos e vai adicionando a uma lista, que poderemos usar em nossa camada de apresentação.

Adicionamos agora vamos adicionar a nossa classe de contexto:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using System.Data.Entity;
  6:
  7: namespace WindowsFormsValidacao
  8: {
  9:     public class Contexto : DbContext
 10:     {
 11:         public DbSet<Produto> Produto { get; set; }
 12:     }
 13: }

Agora vamos adicionar os campos em nosso formulário, que ficará desta forma:

image

O TextBox (txtErros) abaixo do botão Salvar é onde iremos mostrar os erros.

Vamos adicionar um DataSource para podermos trabalhar com nossa classe Produto, para isto vá no menu Data/Add New DataSource e escolha Object:

image

Depois escolha a classe produto:

image

Agora você precisa ligar todos os campos TextBox do formulário aos campos da classe. Para fazer isto, clique sobre o TextBox, vá em propriedades/DataBindings/Text e escolha o campo correspondente ao controle. Faça isto para todos os controles:

image

Após o primeiro campo, escolha os campos sempre a partir do bindingsource:

image

Agora vamos ao código do botão incluir, que simplesmente adiciona um novo objeto Produto vinculado a tela:

  1: private void btnNovo_Click(object sender, EventArgs e)
  2:         {
  3:             produtoBindingSource.AddNew();
  4:         }

E por fim vamos ao código que valida os dados e depois insere no BD:

  1:  private void btnSalvar_Click(object sender, EventArgs e)
  2:         {
  3:             var db = new Contexto();
  4:             db.Database.CreateIfNotExists();
  5:
  6:             var pro = (Produto)produtoBindingSource.Current;
  7:             var erros = pro.Validate();
  8:             if (erros.Count() > 0)
  9:             {
 10:                 txtErros.Text = "";
 11:                 foreach (var err in erros)
 12:                 {
 13:                     txtErros.Text += err + Environment.NewLine;
 14:                 }
 15:             }
 16:             else
 17:             {
 18:                 db.Produto.Add(pro);
 19:                 db.SaveChanges();
 20:                 MessageBox.Show("Produto inserido!");
 21:                 produtoBindingSource.ResetCurrentItem();
 22:             }
 23:         }

Observação: A criação do banco de dados neste ponto é meramente didática, para facilitar o exemplo e não é uma prática recomendável em uma aplicação em produção.

Agora vamos recuperar o produto que está vinculado a tela e logo após vamos chamar o método Validate() que irá retornar a lista de erros que vamos exibir. . Recuperamos o Produto acessando a propriedade Current do BindingSource, mas como ela armazena somente objetos, precisamos converter o valor de Current para o tipo Produto e logo após isto chamamos a validação e caso não exista erros, inserimos o Produto no BD e atualizamos a tela. Os erros são mostrados no campo txtErros na tela.

Você pode formatar a saída do erro modificando o método Validate() na classe ValidacaoEntidade.

Espero que este pequeno exemplo tenha mostrado o quanto é simples fazer validações mesmo em plataformas não tão novas, como o Windows Forms, e isto pode também ser utilizado para validar objetos em camadas separadas da aplicação.

Você pode baixar o código fonte deste exemplo aqui.

Abraços e até a próxima.

Carlos dos Santos.

Oct 03

Curso de C# no IFPR

Nos dias 14 e 15 de setembro eu ministrei um curso básico de C# para os alunos do curso técnico do Instituto Federal do Paraná (www.ifpr.edu.br) a convite do Prof. Rodolfo Barrivieira.

Neste treinamento os alunos tiveram a oportunidade de conhecer a plataforma Microsoft.Net e o Visual Studio 2010, num total de 8 horas de curso.

DSC01678DSC01679DSC01680

Abraços,
Carlos.

Oct 02

TechEd 2011–Palestra Entity Framework

Pessoal,

Este ano tive o prazer de ser palestrante no maior evento de tecnologia Microsoft do Brasil, o TechEd 2011. Confesso que fiquei muito ansioso e também nervoso, pois a responsabilidade em um evento destes é muito grande, e sempre procuramos fazer o melhor. Fiquei muito feliz que a sala ficou praticamente lotada e mais feliz ainda porquê vários amigos foram me prestigiar, então muito obrigado aos amigos Renato Haddad, Fernando Cerqueira, Israel Aece e Bruno Sonnino.

Espero que o evento tenha sido excelente para todos, não só pelo conteúdo técnico, que foi de altíssimo nível, mas também pela oportunidade de fazer contato com novas pessoas, fazer network.

Vejam as fotos da minha palestra:

IMG_6017IMG_6021IMG_6023IMG_6024IMG_6027IMG_6031IMG_6033IMG_6038IMG_6048IMG_6052IMG_6044IMG_6049

O código fonte da palestra pode ser baixado aqui.

Abraços,
Carlos dos Santos.

Oct 02

Brazilian Translation Wiki 2011 Community Participant Award

Pessoal,

Acabei de receber um reconhecimento da Microsoft que me deixou muito contente. Já é o segundo prémio do Translation Wiki que recebo por participar dos trabalhos de moderação da MSDN Library (http://msdn.microsoft.com/pt-br/library), onde basicamento corrigimos os textos traduzidos automaticamente e também os textos da comunidade.

Costumo dizer que é um trabalho interessante e que ajuda também a aumentar meus conhecimentos, pois frequentemente estou acessando os mais variados assuntos.

Vejam abaixo o belíssimo troféu que recebi, juntamente com uma carta de agradecimentos assinada pelo Somasegar (Senior Vice President a Developer Division) e um Microsoft Arc Mouse.

DSC05926

Abraços,
Carlos.

Jun 27

Agile Brazil 2010

Eu estive na quinta e sexta-feira (24 e 25/06) em Porto Alegre/RS para a Agile Brasil 2010 – Conferência Brasileira sobre Métodos Ageis de Desenvolvimento de Software e foi um evento realmente espetacular.

Primeiro por reencontrar vários amigos, depois pelos palestrantes, como Martin Flowler, um dos grandes influenciadores das metodologias ágeis. Nestes dias tivemos várias palestras e workshops , de alto nível, onde pudemos aumentar nosso conhecimento e trocar idéias.

Foi interessante também assistir ao jogo da seleção brasileira durante o evento, que foi transmitido nos telões do auditório principal e até serviram pipocas, show!!!

Para quem não foi, eu definitivamente recomendo que vá no próximo ano, onde teremos o keynote de abertura com Ken Schwaber, fundador da Scrum.org.

foto1
Martin Fowler no keynote de abertura.

foto2
Eu e o André Nobre.

foto3
Philippe Kruchten no keynote da sexta-feira

foto4
Jogo da Seleção Brasileira
foto5foto6
Movimentação durante o evento.
foto7

Fechamento do evento.

Abraços,
Carlos dos Santos