Como validar campos de um formulário? Asp .net C sharp

.NET

12/01/2016

Boa tarde,

Estou precisando validar alguns campos da minha aplicação, campos que não podem ser nulos.
Quando eu deixava o campo em branco dava um erro quando eu ia salvar no banco de dados, para resolver isso utilizei o operado ?:, mas não sei como colocar uma ação na segunda expressão.

Será que alguém pode me ajudar com essa questão, por favor?

Se o campo não for nulo ou vazio ele manda para o banco o valor do campo, se não ele manda um valor nulo (zero).

func._Nome = (!string.IsNullOrEmpty(txtNome.Text) ? (txtNome.Text) : null);


Eu criei uma função que exibe um pop up dizendo que o campo não pode ser nulo e gostaria de chama-la no lugar do NULL.

Porem, acho q ele só vai verificar isso quando for executar o método. Onde eu tenho que fazer a verificação, quando ele for passar os valores para o método ou quando perder o foco do text box? como faço isso?

Comando completo:
protected void btnUpdade_Click(object sender, EventArgs e)
        {
            Funcionarios func = new Funcionarios();

            //atribuindo os valores dos text box para as variáveis no OBJETO
            func._ID = Convert.ToInt32(!string.IsNullOrEmpty(lblID.Text.ToString()) ? (lblID.Text) : null);//Não pode ser NULO
            func._Nome = (!string.IsNullOrEmpty(txtNome.Text) ? (txtNome.Text) : null);//não pode ser nulo
            func._NrReg= Convert.ToInt32(!string.IsNullOrEmpty(txtNreg.Text.ToString()) ? (txtNreg.Text) : null);
            func._Ramal = Convert.ToInt32(!string.IsNullOrEmpty(txtRamal.Text.ToString()) ? (txtRamal.Text) : null);//não pode ser NULO
            func._Empregador = Convert.ToInt32(!string.IsNullOrEmpty(ddlEmpregador.SelectedValue.ToString()) ? (ddlEmpregador.SelectedValue) : null); //não pode ser nulo
            func._Cargo = Convert.ToInt32(!string.IsNullOrEmpty(ddlCargo.SelectedValue.ToString()) ? (ddlCargo.SelectedValue) : null);//não pode ser nulo
            func._Area = Convert.ToInt32(!string.IsNullOrEmpty(ddlArea.SelectedValue.ToString()) ? (ddlArea.SelectedValue) : null);//não pode ser nulo
            func._HrEntra = Convert.ToDateTime(!string.IsNullOrEmpty(txtHrEntra.Text.ToString()) ? (txtHrEntra.Text) : null);
            func._HrSai = Convert.ToDateTime(!string.IsNullOrEmpty(txtHrSai.Text.ToString()) ? (txtHrSai.Text) : null);
            func._DtNasc = Convert.ToDateTime(!string.IsNullOrEmpty(txtDataNasc.Text.ToString()) ? (txtDataNasc.Text) : null);//não pode ser nulo
            func._DtAtu = DateTime.Now;

            try
            {
                func.AlteraFuncionarios();
                lblStatus.Text = ("Dados Atualizados!!!");

                //atualizar grid...
                GridPrincipal.DataSource = func.ListaFuncionarios();
                GridPrincipal.DataBind();

                //limpa text box e combos
                LimpaCampos(this);
                LimpaCombos(this); //ARRUMAR

                //pop up informando que os dados foram alterados
                string alerta = "Dados alterados!!";
                this.ClientScript.RegisterClientScriptBlock(this.GetType(), "alerta", "<script type='text/javascript'>alert('" + alerta + "')</script>"); 
            }
            catch (Exception ex)
            {
                lblStatus.Text = ("Erro na atulização: " + ex);
            }
        }


Mensagem
 //POP UP de campo obrigatório
        public void CampoObrigatorio()
        {
            this.ClientScript.RegisterClientScriptBlock(this.GetType(), "alerta", "<script type='text/javascript'>alert('Campo Obrigatório: ')</script>"); 
        }


obrigado.
Ricardo

Ricardo

Curtidas 0

Respostas

Joel Rodrigues

Joel Rodrigues

12/01/2016

Neste caso você pode fazer validações em dois momentos:
1) No front-end, usando atributos da HTML5 e plugins jQuery (jQuery Validate) para validar os campos enquanto são preenchidos.
2) No momento da submissão dos dados, ou seja, quando você clica em "Enviar" ou "Salvar".

Adicionalmente, para esconder essa lógica da camada de apresentação, você pode fazer essas validações simples nos getters e setters das propriedades. Por exemplo:

private string nome;
public string Nome
{
    get { return nome; }
    set
    {
        if(String.IsNullOrWhiteSpace(value))
            throw new CampoInvalidoException("O campo Nome não pode ficar vazio");
        nome = value;
    }
}


Existem, no entanto, sugestões de que não se faça validações com exceções no domínio, que sejam criadas classes especializadas para isso. Cabe a você avaliar a necessidade do seu projeto.
GOSTEI 0
Ricardo

Ricardo

12/01/2016

Joel, bom dia.

Obrigado pela resposta.

Interessante isso, eu estou fazendo algo parecido com isso no evento do botão por enquanto, mas vou criar uma classe VALIDAR, para testar as coisas antes de enviar para os métodos.

Na verdade, por enquanto, eu só estou vendo se algo foi digitado no campo utilizando o "!string.IsNullOrEmpty" no if, mas acho que posso utilizar "!String.IsNullOrWhiteSpace", como vc disse acima.

protected void btnSavePj_Click(object sender, EventArgs e)
        {
            ClientePJ clientePj = new ClientePJ();
           
            //verificando se os campos obrigatorios estão preenchidos
            //se os textbox forem validos, os valores são passados para os parametros, se não forem validos os campos incorretos serão destacados
            if (!string.IsNullOrEmpty(txtRazSoc.Text) && !string.IsNullOrEmpty(txtCnpj.Text) && !string.IsNullOrEmpty(txtEnd.Text) && !string.IsNullOrEmpty(txtNum.Text))
            {
                //atribui valor aos parametros
                clientePj._nome = txtRazSoc.Text;
                clientePj._cnpj = txtCnpj.Text;
                clientePj._endereço = txtEnd.Text;
                clientePj._num = Convert.ToInt32(txtNum.Text);
                clientePj._complemento = txtComplemento.Text;
                //clientePj._complemento = (!string.IsNullOrEmpty(txtComplemento.Text) ? txtComplemento.Text : " ");
                clientePj._email = txtEmail.Text;
                clientePj._tel = txtTel.Text;
 
                try
                {
                    //chama o metodo para salvar o cadastro
                    clientePj.SavePj();
 
                    //msg avisando que o cadastro foi salvo
                    lblMsg.Text = "Cadastro Salvo";
 
                    //testa parametros
                    lblNome.Text = clientePj._nome;
                    lblCnpj.Text = clientePj._cnpj;
                    lblEndereço.Text = clientePj._endereço;
                    lblNum.Text = Convert.ToString(clientePj._num);
                    lblComplemento.Text = clientePj._complemento;
                    lblEmail.Text = clientePj._email;
                    lblTel.Text = clientePj._tel;
                }
                catch(Exception ex)
                {
                    lblMsg.Text = ("erro ao salvar o cadastro: " + ex);
                }//fim catch
              
            }//fim if
            else
            {
                lblMsg.Text = "Preencha todos os campos obrigatorios!!!";
            }//fim else
 
            //marca campo obrigatórios não preenchidos
            lblAsteriscoNome.Visible=      (!string.IsNullOrEmpty(txtRazSoc.Text)? false : true);
            lblAsteriscoCnpj.Visible =     (!string.IsNullOrEmpty(txtCnpj.Text) ? false : true);
            lblAsteriscoEndereço.Visible = (!string.IsNullOrEmpty(txtEnd.Text) ? false : true);
            lblAsteriscoNum.Visible =      (!string.IsNullOrEmpty(txtNum.Text) ? false : true);
        }//fim evento SavePJ


Esse trecho de código foi apenas o teste, na minha aplicação eu verifico se o CPF é valido utilizando um metodo de validação de CPF, vou pesquisar outros métodos para validar Nome, Telefone, e-mail.... enfim todos os campos, por que do jeito que eu fiz até agora qualquer coisa digitada nesses campos ele vai aceitar. E todos esses métodos para verificar se o campo está correto vão estar em uma única classe VALIDAR, acho que foi isso que você sugeriu, certo?

Eu relutei bastante antes de validar utilizando os ifs, mas acho que é assim mesmo que tem que ser feito, ai vem a grande questão, isso é gosto de quem me explicou? assim é o jeito mais facil? ou será o jeito certo mesmo? Por que estou aprende isso agora em foruns e conversas com amigos, mas nenhum deles programas em C#, a maioria usa VB (windows form) e PHP.

Estou desenvolvendo uma aplicação para um cadastro de clientes, o cliente vai preencher os dados e enviar os documentos para analise, na verdade estou fazendo um teste com poucos campos, apenas para aprender antes de fazer o formulário completo.

Nesse projeto estou utilizando um monte de PANELS, isso é viavel?
Todos os panel estão ocultos, e de acordo com as opções do usuário eu vou exibindo os proximos panels e ocultando os que não serão mais utilizados.

Esse é o meu evento para salvar o pre cadastro do cliente

 protected void btnConfirmaDadosPreCadPf_Click(object sender, EventArgs e)
        {
            //chamar metedo para salvar o pre cadastro no banco de dados
            ClientePF clientePf = new ClientePF();
            Operação operação = new Operação();

            //lblMsgPreCad.Text= (!string.IsNullOrEmpty(txtCpfPreCadPf.Text) ? "CPF Invalido" : "");
            //lblAsteriscoCpfPre.Visible= (!string.IsNullOrEmpty(txtCpfPreCadPf.Text) ? false : true);

            operação._idTipoOp = Convert.ToInt16(ddlTipoOpPreCadPf.SelectedValue);

            clientePf._cpf = txtCpfPreCadPf.Text;

            if (clientePf.CpfOk(clientePf._cpf) == true)
            {
                clientePf.PegaDados();

                lblAsteriscoCpfPre.Visible = false;
                //verifica se o cliente possui cadastro
                if (clientePf._id == 0)
                {
                    //cliente novo
                    //verifica se os campos obrigatorios estão preenchidos
                    if (!string.IsNullOrEmpty(txtNomeCliPreCadPf.Text) && !string.IsNullOrEmpty(txtEndereçoPreCadPf.Text) && !string.IsNullOrEmpty(txtNumPreCadPf.Text) && !string.IsNullOrEmpty(lblAsteriscoTelResPre.Text) && !string.IsNullOrEmpty(txtTelComPreCadPf.Text) && !string.IsNullOrEmpty(txtTelCelPreCadPf.Text) && !string.IsNullOrEmpty(txtEmailPreCadPf.Text))
                    {
                        //efetua o cadastro

                        //passando valores para o metodo
                        clientePf._nome = txtNomeCliPreCadPf.Text;
                        clientePf._cpf = txtCpfPreCadPf.Text;
                        clientePf._endereço = txtEndereçoPreCadPf.Text;
                        clientePf._num = Convert.ToInt32(txtNumPreCadPf.Text);
                        clientePf._complemento = txtComplementoPreCadPf.Text;
                        clientePf._telres = txtTelResPreCadPf.Text;
                        clientePf._telcom = txtTelComPreCadPf.Text;
                        clientePf._celular = txtTelCelPreCadPf.Text;
                        clientePf._email = txtEmailPreCadPf.Text;

                        //Salvando o PRE CADASTRO
                        clientePf.SavePreCadPf();

                        //Obtendo o ID do cliente que acabade ser cadastrado
                        clientePf.PegaDados();

                        //chamar metodo para salvar a operação
                        operação._idCli = clientePf._id;
                        //operação._idTipoOp = Convert.ToInt16(ddlTipoOpPreCadPf.SelectedValue);
                        operação._dtInicio = DateTime.Now;
                        operação._idStatusOp = 1;

                        //Salvando a OPERAÇÃO
                        operação.SaveOp();

                        //passando o id da operção para o label no panel de seleção de documento
                        operação.PegaLastId();
                        lblIdOperação.Text = Convert.ToString(operação._idOperacao);

                        //aqui é salvo o pre cadastro e a nova operação do cliente

                        //confimar operação - passando os IDs do CLIENTE e OPERAÇÃO para o PANEL de CONFIRMAÇÂO da OPERAÇÃO
                        //se o cliente não confirmar a operação os dados serão excluidos
                        lblConfIdCliPfNovo.Text = Convert.ToString(clientePf._id);
                        lblConfIdOpCliPfNovo.Text = Convert.ToString(operação._idOperacao);

                        //habilita panel de seleção de documentos
                        pnlSelecionarDocs.Visible = true;
                        //desabilita funções do panel de pre cadastro
                        btnConfirmaDadosPreCadPf.Enabled = false;
                        pnlPreCadPf.Enabled = false;
                    }//fim if verifica campos obrigatorios

                    else //iforma campos a serem preenchidos / corrigidos
                    {
                        lblAsteriscoNomePre.Visible =   (!string.IsNullOrEmpty(txtNomeCliPreCadPf.Text)? false:true);
                        lblAsteriscoEndPre.Visible =    (!string.IsNullOrEmpty(txtEndereçoPreCadPf.Text) ? false : true);
                        lblAsteriscoNumPre.Visible =    (!string.IsNullOrEmpty(txtNumPreCadPf.Text) ? false : true);
                        lblAsteriscoTelResPre.Visible = (!string.IsNullOrEmpty(txtTelResPreCadPf.Text) ? false : true);
                        lblAsteriscoTelComPre.Visible = (!string.IsNullOrEmpty(txtTelComPreCadPf.Text) ? false : true);
                        lblAsteriscoTelCelPre.Visible = (!string.IsNullOrEmpty(txtTelCelPreCadPf.Text) ? false : true);
                        lblAsteriscoEmailPre.Visible =  (!string.IsNullOrEmpty(txtEmailPreCadPf.Text) ? false : true);
                        lblAsteriscoTipoOpPre.Visible = ((operação._idTipoOp == 5) ? true : false); //id 5 = --Selecione--

                        lblMsgPreCad.Visible = true;
                        lblMsgPreCad.Text = "Preencha todos os campos obrigatorios corretamente";
                    }

                }//fim if verifica se o cliente possui cadastro
                
                else //if cliente possui cadastro = SIM
                {
                    lblMsgPreCad.Visible = true;
                    lblMsgPreCad.Text = "CPF Cadastrado";
                    lblAsteriscoCpfPre.Visible = true;
                }//fim else IF cliente possui cadastro

            }// fim if CPF OK

            else //if cpfok
            {
                lblMsgPreCad.Visible = true;
                lblMsgPreCad.Text = "Digite um CPF valido";
                lblAsteriscoCpfPre.Visible = true;
            }//fim else CPF OK

        }//Fim botão Confirma Dados


Nesse evento eu testo primeiro o CPF e se o CPF for valido eu verifico se os outros campos obrigatorios estão preenchidos, caso algum não esteja eu exibo uma mensagem ao lado do botão e coloco os asteriscos no campos que necessitam de preenchimento.

Mas estou com alguns problemas, a mensagem informando que todos os campos obrigatorios precisam ser preenchidos não sai da tela enquanto o botão não for clicado novamente, e o outro problema é que os campos são verificados apenas quando o botão é clicado.

Estava vendo um exemplo de mascaras para os texts box, onde o cara fazia algo no enveto click do text box, mas acho q isso só funcionar para windows form.

Bom Joel, como estou aprendendo agora todas as dicas são bem vindas, pois quero aprender do jeito certo.

Obrigado.
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

12/01/2016

Acredito que você esteja fazendo isso em Web Forms, certo? Como está no início, já começo lhe sugerindo a usar MVC e você verá como fica simples essa questão de validação.

Eu vou criar aqui um pequeno projeto em ASP.NET MVC e lhe enviar, explicando passo a passo para que você veja como é simples criar um cadastro (que é o exmplo básico, mas pode ser expandido) com validações.

Enviarei aqui o link dentro de instantes.
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

12/01/2016

Pronto, criei o projeto de exemplo e você pode baixá-lo no link https://github.com/joelrlneto/CadastroBasicoASPNETMVC.

Lá tem a descrição dos passos necessários para reproduzir o exemplo.
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

12/01/2016

1. Criar novo projeto ASP.NET MVC:
- File > New > Project > C# > Web > ASP.NET Web Application;
- Escolher o template MVC e manter marcado apenas MVC na parte inferior.

2. Instalar o Entity Framework via NuGet:
- Tools > NuGet Package Manager > Package Manager Console;
- Digitar: `Install-Package EntityFramework`.

3. Criar as classes do Model:
- Adicionar nova classe de entidade na pasta Models (aqui se chamará Cliente, ver o código no projeto);
- Adicionar DbContext na pasta Models (ver código no projeto);
- Adicionar Connection String no arquivo Web.config (ver código no projeto).

4. Adicionar Controller:
- Clicar com a direita na pasta Controllers e em Add > Controller;
- Escolher "MVC5 Controller with views using Entity Framework";
- Em "Model class" escolher a classe de entidade (nesse exemplo, Cliente) e em "Data context class" escolher o DbContext criado (nesse exemplo, BancoDeDados);
- Manter as opções selecionadas e clicar em Add.

Agora já pode executar a aplicação e o CRUD de clientes estará pronto. Quando a aplicação abrir no browse, acesse a URL `locahost:[porta]/Clientes` e verá a listagem de clientes com opção para inserir novo.
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

12/01/2016

Lhe aconselho dar uma olhada nessa série de vídeos sobre ASP.NET MVC produzida pelo Cleyton Ferrari, que é participante ativo da comunidade técnica e membro do programa MTAC (Microsoft Technical Audience Contributor). É considerado um dos melhores "cursos" para iniciantes em ASP.NET MVC: [url:descricao=ASP.NET MVC na Prática]https://www.youtube.com/watch?v=VbA_JZJtKaY&list=PLGsgFU2A1wDeOqZfkOVAO6YJhRMsLbCJJ[/url].
GOSTEI 0
Ricardo

Ricardo

12/01/2016

Legal Joel, obrigado pela dica e pela a ajuda.

Sim, estou fazendo em web form.

Qual versão do visual studio você está utilizando? Pois tentei abrir o seu projeto aqui e deu um erro dizendo que a minha versão do vs não suporta esse projeto. Estou usando o Visual Studio 2012 Express for Web, e só tem o MVC 3 e 4 aqui. vou instalar uma versão mais recente do vs para ver se resolve.

Vou dar uma olhada no MVC, e provavelmente quando eu for começar a desenvolver a aplicação pra valer mesmo eu faça eu MVC, já que o web form tende a sumir. A microsoft fez algo parecido com o Sharepoint Designer, não sei se você conhece. Eu fiz a intranet da empresa em que trabalho utilizando o Sharepoint, aprendi tudo utilizando a versão 2012 do sharepoint em uma maquina de testes e quando fui fazer a versão final no servidor web utilizei a versão 2012 do sharepoint, e a parte "visual (DESIGN e SPLIT)" da modelagem da página não estava mais na ferramenta, fiz tudo no SOURCE, mas a barra de ferramentas ainda está lá, eu clico duas vezes sobre o componente e o código dele é inserindo na página. Ainda faço isso, acho q 80% do design da aplicação eu fiz assim, uma coisa ou outra que eu vou na barra de propriedades para alterar.

A principio, comecei a aprender isso para adicionar algumas coisas dinâmicas na intranet, para todas as atualizações serem feitas apenas uma vez e não no sistema e depois atualizadas na intranet, espero conseguir fazer isso. Mas surgiu esse projeto, e se eu conseguir desenvolver vai ser ótimo. Eu vejo ele como uma coisa relativamente simples, mas muitoooo trabalhosa. Simples no sentido que é só pegar os dados do cadastro feito pelo site e enviar para um operador que irá conferir os dados e aprovar ou não o cadastro, antes do cadastro ser aprovado ele vai ficar no banco de dados de onde o site está hospedado e após sua aprovação os dados serão enviados para o servidor da empresa em que trabalho. Bom, pelo menos é assim que eu acho q vai funcionar.... não sei muito bem como funciona a relação do banco com a aplicação, mas acho que os 2 tem que estar no mesmo servidor.

Vou assistir os videos que você recomendou e atualizar o meu vs, mas acho q a ultima versão dele só funcionar no windows 10, e eu voltei para o windows sete. Instalei o VS 2012 pq é a mesma versão que estou usando para fazer os testes onde eu trabalho, mas qualquer coisa atualizo lá tbm.

Com certeza muitas dúvidas surgirão ainda, mais do que as que ainda tenho...rss

Por acaso tem um cronograma a ser seguindo para o desenvolvimento de um sistema/aplicação, ou cada programador segue um caminho?

No meu projeto eu montei primeiro o banco de dados, fiz todos os relacionamentos e criei as tabelas, depois fiz as classes e métodos e por ultimo o layout. Como eu não sabia verificar os campos eu fiz tudo funcionar e agora fiz as verificações. Como estou em processo de aprendizagem tenho q ir e voltar algumas vezes antes de ficar tudo certo, mas se eu tivesse um cronograma eu persistiria mais em cada etapa antes de ir para a etapa seguinte, talvez com o tempo eu faça isso.

Obrigado.
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

12/01/2016

Use o Visual Studio 2015 Community Edition, é completo e gratuito.

Sobre o fluxo de desenvolvimento, partir do banco de dados é comum, no entanto hoje utiliza-se mais a prática de partir do domínio da aplicação, escrevendo as classes e utilizar um framework ORM (Object-Relational Mapping) como o Entity Framework que usei nesse projeto. Após criar as classes, o próprio ORM cria o banco, dessa forma você não precisa trabalhar diretamente no banco ou com SQL.

Comece a estudar ASP.NET MVC e Entity Framework (especialmente o método Code First).
GOSTEI 0
Ricardo

Ricardo

12/01/2016

Joel bom dia.

Estou acompanhando os videos que você recomendou, muito bom. Estou bem no inicio ainda, vi apenas 3 videos, e as validações pelo MVC são bem mais tranquilas, pelo menos as mostradas até agora.

Mas eu sou muito ansioso e tenho dúvidas que provavelmente serão respondidas nos próximos videos...rss Por exemplo, no meu projeto em alguns momentos eu terei que fazer operações com classes diferentes na mesma "ação", tipo inserir um registro na tabela cliente do banco de dados, fazer um select para saber o ID do cliente para pode inserir o tipo de operação na tabela TipoOperação, mas isso não deve ser muito dificil.

Pra mim ainda não está muito claro ainda onde eu tenho que colocar as minhas classes e escrever meus metodos das classes, no web form eu criava uma classe para cada tabela do banco de dados e algumas classes globais ou auxiliares e depois ia chamando nos eventos ou entre elas mesmo. E agora parece que para a mesma tabela eu preciso ter 2 classes, uma só com os atraibutos (id, nome, rg, cpf) e outra com os metodos (insere, busca, deleta, altera...). Pelo menos foi isso que eu percebi em alguns exemplos que vi pela internet, e isso fica na pasta MODELS. Isso que tem que ficar claro pra mim, mas até o final do "curso" acho q isso ficara bem claro.

Em relação ao seu exemplo, ainda não consegui abrir, eu instalei o community 2015 aqui, mas quando eu vou criar um novo projeto não aparece as opções de MVC, na verdade só aparece "ASP . NET Web Application", vou dar uma pesquisada para saber o que eu fiz de errado ou como faço para aparecer as outras opções de projeto.

Valeu...
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

12/01/2016

Com relação a criar um projeto ASP.NET MVC, é exatamente pelo template Web Application (veja o passo 1 que indiquei acima).
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

12/01/2016

Sobre a separação de responsabilidades entre as classes, é algo que vamos aprendendo com o tempo. É comum que no início criemos uma classe que faz de tudo, e de fato ela resolve nossos problemas, mas temos de evoluir constantemente a qualidade do código que escrevemos e para isso é fundamental seguir alguns padrões e boas práticas.

Para facilitar, pense assim para saber onde colocar as classes:
- Models: classes do domínio e acesso a banco de dados;
- View: interface gráfica (páginas HTML/CSS/JS);
- Controllers: classes que controlarão o fluxo da aplicação (recebem e enviam os dados das requisições, etc).

É importante que você primeiramente entenda o modelo MVC, pois isso lhe será útil se futuramente precisar trabalhar com outras linguagens.
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

12/01/2016

Ainda sobre a divisão de responsabilidades, uma das divisões mais comuns é a que utiliza as camadas DAL (Data Access Layer) e BLL (Business Logic Layer). Algumas usam ainda os DTO (Data Transfer Objects) para trafegar os dados entre camadas.

Lhe aconselho, porém, a utilizar o Entity Framework seguindo o exemplo que dei, pois você verá que todas as operações de acesso ao banco já são definidas por ele e você não precisa mais se preocupar com isso. Você basicamente escreverá a classe do domínio (Cliente, Produto, Pessoa, etc) e mapeará ela como uma tabela do banco (o que é feito pelo EF). Daí pra frente, operações como CRUD e buscas complexas podem ser feitas sem usar SQL.
GOSTEI 0
Ricardo

Ricardo

12/01/2016

Joel, boa tarde.

Ainda não consegui analisar o seu exemplo, estou tentando entender um pouco sobre o assunto para não ficar muito perdido.

Estou seguindo um livro de ASP .NET MVC, e já estou com problemas... Estou tentando fazer a ligação com o banco de dados utilizando o Entity Framework.

No exemplo do livro tenho que criar duas classes POCO (Posts e Categorias) e uma classe de amarração. Mas quando eu vou criar os controllers ele da um erro dizendo que a connection string está errada...

No livro ele não fala nada sobre os name spaces, eu vi na internet quais deveriam ser usados.

Tentei criar o banco de dados primeiro e não deu certo tbm, deu o mesmo erro. Mas acho que era para o EF criar o banco pra mim, certo? Esse exemplo é de Code First.

Antes de criar os controller o livro diz q eu preciso executar um BUILD, seria o (Build Solution ctrl+shift+B???)

Seguem as classes...

Models --> Classe Categorias

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations; //NameSpace para poder utilizar o atributo [Key]

namespace AplicacaoComCodeFirst.Models
{
    public class Categorias
    {
        [Key]
        public int CategoriaID {get;set;}

        public string Categoria {get;set;}

        public string Descricao {get;set;}

        public virtual ICollection<Posts> Posts {get;set;}
    }
}


Models --> Classe Posts

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations; // NameSpace para utilizar o atributo [Key]
using System.ComponentModel.DataAnnotations.Schema; // NameSpace para utilizar o atributo [ForeignKey]

namespace AplicacaoComCodeFirst.Models
{
    public class Posts
    {
        [Key]
        public long PostID {get; set;}
        
        public string TituloPost {get; set;}
        
        public string ResumoPost {get; set;}
        
        public string ConteudoPost {get; set;}
        
        public DateTime DataPostagem {get; set;}
        
        public int CategoriaID {get; set;}

        [ForeignKey("CategoriaID")]
        public virtual Categorias Categorias {get; set;}
    }
}


Model --> BlogContext

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity; // NameSpace para utilizar o DbSet

namespace AplicacaoComCodeFirst.Models
{
    public class BlogContext : DbContext
    {
        public BlogContext() : base("name=BlogContext")
        {
            //informando a string de conexão com o banco de dados
            //string strcon = "Data Source=WIN-MKVUVQQTTBL\\RPAZZINI;Initial Catalog=BlogBDLivro;Integrated Security=True"; // usuario e senha: User ID=sa;Password=123456");
            Database.Connection.ConnectionString = (@"Data Source=WIN-MKVUVQQTTBL\\RPAZZINI;Initial Catalog=BlogBDLivro;Integrated Security=True");
        }

        public DbSet<Posts> Posts { get; set; }
        public DbSet<Categorias> Categorias { get; set; }
    }
}


Controller --> CategoriasController
[img:descricao=CategoriasController]http://arquivo.devmedia.com.br/forum/imagem/451395-20160222-151744.png[/img]

Erro
[img:descricao=Erro]http://arquivo.devmedia.com.br/forum/imagem/451395-20160222-151904.png[/img]

Essa connection string funciona, pelo menos com web form.

Valeu..
GOSTEI 0
Jothaz

Jothaz

12/01/2016

Adicionou a string de conexão no web.config:

  <connectionStrings>
    <add name="name=BlogContext" connectionString="Data Source=;Initial Catalog=;User ID=;Password=" providerName="System.Data.SqlClient" />
  </connectionStrings>


 public BlogContext() : base("name=BlogContext")   {}
GOSTEI 0
Ricardo

Ricardo

12/01/2016

Jothaz, bom dia.

Não deu certo aqui, continua dando a mesma mensagem

<connectionStrings>
    <!--
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-AplicacaoComCodeFirst-20160224102703;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-AplicacaoComCodeFirst-20160224102703.mdf" providerName="System.Data.SqlClient" />
    -->

    <add name="DefaultConnection" connectionString="Data Source=~\RPAZZINI;Initial Catalog=BlogBDLivro;User ID=sa;Password=123456" providerName="System.Data.SqlClient" />
  </connectionStrings>


Se eu criar os controllers sem especificar o banco de dados funciona, porem eu não sei onde esse banco está, não encontrei ele aqui no SQL.

Fiz a conexão com o banco pelo vs, e a connection string gerada foi: Data Source=WIN-MKVUVQQTTBL\RPAZZINI;Initial Catalog=BlogBDLivro;Persist Security Info=True;User ID=sa;Password=***********

No web form eu utilizo essa conection string para fazer a conexão, só tenho que adicionar uma barra entre o nome do servidor e o nome da base.

No livro diz, que o comando vai criar o banco de dados BlogBDLivro, indicado pelo Initial Catalog, é isso mesmo? Eu mesmo criei esse banco no SQL.

O que estou fazendo de errado na hora de indicar o local onde quero criar o banco e as tabelas?
GOSTEI 0
Ricardo

Ricardo

12/01/2016

Agora ele criou o controller, eu refiz todo o projeto e tinha esquecido de colocar o nome da conexão no web config. Mas não está criando as tabelas e está dando erro na connection string...

[img]http://arquivo.devmedia.com.br/forum/imagem/451395-20160224-115638.png[/img]

[img]http://arquivo.devmedia.com.br/forum/imagem/451395-20160224-115711%20%281%29.png[/img]
GOSTEI 0
Ricardo

Ricardo

12/01/2016

Consegui acertar aqui...

  <connectionStrings>
    <add name="BlogContext" connectionString="Data Source=WIN-MKVUVQQTTBL\RPAZZINI;Initial Catalog=BlogBDLivro;User ID=sa;Password=123456" providerName="System.Data.SqlClient" />
  </connectionStrings>


obrigado...
GOSTEI 0
Jothaz

Jothaz

12/01/2016

O erro em questão e ao acessar o banco de dados e pode se originar de várias causas, tais como:

1-Sua servidor de banco de dados esta aceitando conexão TCP/IP? Pela mensagem acho que o problema pode ser este.

2-A string de conexão usada no web.config esta correta? Tente conectar ao banco de dados via Visual Studio e copie a string de conexão gerada.

3-O servidor esta mesmo funcionando, testou usando por exemplo o Management Studio.
GOSTEI 0
Ricardo

Ricardo

12/01/2016

Jothaz, a string de conexão estava incorreta.

agora estou com outro problema, estou seguindo com o livro e agora vai começar a parte de controllers e logo no inicio está dando erro, assim como aconteceu nos capítulos anteriores.

Bom, nessa aplicação eu criei o banco de dados pelo SQL e depois vinculei ele à aplicação utilizando o entity framework, até ai tudo bem, ele gerou as classes do banco de dados e eu criei novas classes (classes parciais) para fazer a validação dos campos.

Quando criei o primeiro controller ele está falando "Error 1 Cannot convert lambda expression to type 'string' because it is not a delegate type"

Controller MedicosController

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using CadeMeuMedico.Models;

namespace CadeMeuMedico.Controllers
{
    public class MedicosController : Controller
    {
        private EntidadesCadeMeuMedicoBD db = new EntidadesCadeMeuMedicoBD();


        public ActionResult Index()
        {
            var medicos = db.Medicos.Include(m => m.Cidade).Include(m => m.Especialidade).ToList();
            return View(medicos);
        }
    }
}


ele marca como errado "m=>m.Cidade", mas se eu inverto a ordem colocando (m=>m.Especialidade) na frente, o erro fica nele.

Esses dois campos são chaves estrangeiras na minha tabela Medicos. Pelo o que eu entendi, ele faz referencia à classe que eu criei para validar os campos.

Classe que valida CIdades
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace CadeMeuMedico.Models
{
    [MetadataType(typeof(CidadesMetadados))]
    public partial class Cidades
    {
    }

    public class CidadesMetadados
    {
        [Required(ErrorMessage = "Obrigatório informar a cidade")]
        [StringLength(30, ErrorMessage = "A cidade deve possuir no máximo 80 caracteres")]
        public string Cidade { get; set; }
    }
}


Classe Cidades gerada pelo EF
//------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated from a template.
//
//    Manual changes to this file may cause unexpected behavior in your application.
//    Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace CadeMeuMedico.Models
{
    using System;
    using System.Collections.Generic;
    
    public partial class Cidades
    {
        public Cidades()
        {
            this.Medicos = new HashSet<Medicos>();
        }
    
        public int IDCidade { get; set; }
        public string Nome { get; set; }
    
        public virtual ICollection<Medicos> Medicos { get; set; }
    }
}


O estranho é que está exatamente como no livro, e até agora em todos os capítulos tive que fazer alguma alteração ou pesquisar algo para os exemplos funcionarem e o livro é "novo", é de 2014...

Valeu.
GOSTEI 0
Ricardo

Ricardo

12/01/2016

Como eu faço para utilizar os atributos atributos das minhas tabelas do banco de dados?

Eu criei uma instancia do meu banco de dados, e através dela eu consigo instanciar outro objeto com uma tabela especifica do banco de dados, mas não consigo utilizar os atributos dessa tabela.

Por exemplo, no meu banco de dados tem uma tabela chamada MEDICO com o atributo nome. Eu criei uma instancia do banco de dados BD e com ela consigo utilizar todas as tabelas... BD.MEDICO isso está ok, mas eu não consigo utilizar o atributo NOME ==> BD.MEDICO.NOME, qndo faço isso da erro...
"'CadeMeuMedico.Models.Medico' does not contain a definition for 'IDCidade' and no extension method 'IDCidade' accepting a first argument of type 'CadeMeuMedico.Models.Medico' could be found (are you missing a using directive or an assembly reference?)"

Eu utilizei o Entity Framework para vincular o meu banco de dados ao VS, ele gerou algumas classes (classes parciais), dei uma olhada nessas classes e todos os atributos estão como publico... Onde eu tenho que ir para resolver isso??

Como ainda não sei direito os termos que utilizar na minha pergunta, segue Controller que está apresentando os erro para um melhor entendimento. Os erros estão em "db.Medicos.Add(medico);", "..., medico.IDCidade);" e "..., medico.IDEspecialidade);"

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using CadeMeuMedico.Models;
using System.Data;
using System.Data.Entity;


namespace CadeMeuMedico.Controllers
{
    public class MedicosController : Controller
    {
        private EntidadesCadeMeuMedicoBD db = new EntidadesCadeMeuMedicoBD();

        public ActionResult Index()
        {
            ///no livro está assim - Pg. 86
            ///mas dessa forma da erro na expressão lambda....
            //var medicos = db.Medicos.Include(m => m.Cidade).Include(m => m.Especialidade).ToList();
            
            var medicos = db.Medicos.Include("Cidades").Include("Especialidades").ToList();
            return View(medicos);
        }

        
        public ActionResult Adicionar()
        {
            ViewBag.IDCidade = new SelectList(db.Cidades, "Cidades", "Nome");
            ViewBag.IDEspecialidade = new SelectList(db.Especialidades, "IDEspecialidades", "Nome");
            return View();
        }

        [HttpPost]
        public ActionResult Adicionar(Medico medico)
        {
            if (ModelState.IsValid)
            {
                db.Medicos.Add(medico);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            ViewBag.IDCidade = new SelectList(db.Cidades, "IDCidade", "Nome", medico.IDCidade);
            ViewBag.IDEspecialidade = new SelectList(db.Especialidades, "IDEspecialidade", "Nome", medico.IDEspecialidade);
            
            return View(medico);
        }

    }
}


Obrigado.
GOSTEI 0
Ricardo

Ricardo

12/01/2016

Achei o problema aqui... por algum motivo ele traz Medico e MedicoS no auto completar quando eu começo a digitar, e ta dando erro pq eu criei um objeto do tipo Medico, mas o correto seria do tipo MedicoS......

Mas o motivo do erro na expressão lambda eu não achei ainda, alterei o código daquela forma pq o livro disponibiliza todo o código do projeto para download....

Valeu....
GOSTEI 0
Ricardo

Ricardo

12/01/2016

Boa tarde,

Fiz a ligação com o banco de dados utilizando o entity framework, ele criou o diagrama e as classes parciais do banco, agora precisei adicionar uma nova tabela no meu banco de dados e não sei como fazer isso no meu projeto.

Eu cliquei com o botão direto do mouse em uma área em branco do diagrama e fui em "update model from database", selecionei a nova tabela e cliquei em finish, a nova tabela apareceu no diagrama, mas a classe não foi criada.

Como faço para a classe parcial da nova tabela ser criada automaticamente pelo EF?

Att.,
GOSTEI 0
Ricardo

Ricardo

12/01/2016

Boa tarde,

Jotaz, obrigado pela ajuda com a Connection string e pela ajuda e dicas nos outros tópicos que postei aqui no fórum.

Joel, obrigado pelo exemplo e pelas dicas.

Bom, eu li um livro de ASP .NET MVC e assisti as videos aulas que você (Joel) recomendou, porem fiquei com uma dúvida em como fazer a manipulação do banco de dados.

1 - Devo usar ADO ou Entity Framework?

2 - Na utilização do entity framework, é melhor eu fazer o mapeamento do banco utilizando o visual studio (New item --> ADO .NET Entity Data Model) ou criar tudo manualmente (classe de contexto herdando de DbContext, e as classes referentes a cada tabela do meu banco de dados) na pasta models?

3 - Outra coisa sobre a utilização de repositórios, nas videos aulas o exemplo dado foi utilizando repositórios, mas não ficou muito claro isso pra mim, pelo que eu entendi eu preciso criar DLL's (new project --> class library),
uma DLL para as Entidades (bancos de dados) com a classe de contexto e as classes das tabelas;
e uma DLL com os métodos que serão executados, nessa classe preciso ter uma interface que diz quais métodos serão executados;
e um projeto ASP .NET onde eu informo a strig de conexão e chamo os métodos nas actios...
Isso ainda está bem confuso pra mim....

Sobre o ADO .NET e o Entity Framework, pelo o que eu entendi o EF veio para facilitar a manipulação dos dados, já que as expressões lambdas são mais "curtas" do que os sql commands...

Você conhece algum tutorial bom sobre EF e expressão lambda? pois estou apanhando bastante aqui em algumas consultas...

Obrigado.
GOSTEI 0
POSTAR