quinta-feira, 24 de outubro de 2013

Objeto para String - Serializar

Imagine que você tem um objeto e queira guardar ele em  banco de dados ou em um arquivo XML no seu estado atual.
Para isso precisaremos serializar o objeto jogando o valor para uma string.

Temos o seguinte objeto:
public class usuario
{

    public string nome;
    public string email;
    public bool ativo;
}


Precisaremos criar dois métodos, um que pega um determinado objeto e o transforma em string o outro fará o inverso.

  public static string ParaString<T>(this T valor)
  {
      XmlSerializer xml = new XmlSerializer(valor.GetType());
      StringWriter retorno = new StringWriter();
      xml.Serialize(retorno, valor);
      return retorno.ToString();
  }
  public static object ParaObjeto(string valor, Type tipo)
  {
      XmlSerializer xml = new XmlSerializer(tipo);
      var valor_serealizado = new StringReader(valor);
      return xml.Deserialize(valor_serealizado);
  }



Vou criar uma instância dessa classe com o nome de u.
usuario u = new usuario();
       u.nome = "Celso";
       u.email = "czequim@gmail.com";
       u.ativo = true;
já temos o nosso objeto criado agora precisamos serealizar.
string retorno = ParaString<usuario>(u);

O conteúdo da variável retorno será:
<usuario xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <nome>Celso</nome>
  <email>czequim@gmail.com</email>
  <ativo>true</ativo>
</usuario>

Agora se você tem esse valor em uma string e quiser fazer o inverso, transformar esse xml em um objeto. É só chamar o segundo método.
usuario Objeto =(usuario) ParaObjeto(retorno, u.GetType());


Simples assim. :D

Se for um List o processo é o mesmo.
Veja o exemplo:
List<usuario> usuarios = new List<usuario>();

     for (int i = 0; i < 10; i++)
     {
usuario u = new usuario();
       u.nome = "Celso";
u.email = "czequim@gmail.com";
       u.ativo = true;           
     }
           

     string retorno = ParaString<List<usuario>>(usuarios);          
           
           
     List< usuario> Objeto =(List<usuario>) ParaObjeto(retorno, usuarios.GetType());


simples assim também.... :D

terça-feira, 17 de setembro de 2013

Implementando Callbacks

O que é Callback?
É uma das formas de enviar uma informação ao servidor sem atualizar ou submeter a página atual.

Esse exemplo que eu vou dar a seguir é o básico do básico, como um campo de busca com sugestões, que  ao digitar uma informação o sistema automaticamente irá buscar no servidor atualizando um painel com os possíveis resultados.

o arquivo ASPX ficará assim:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="callback._default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
  <title>teste autocomplete</title>
  <script type="text/ecmascript">
      function Buscar() {
          var lb = document.getElementById("busca").value;

          CallServer(lb, "");         
      }
      function Retorno(rValue)
      {         
          document.getElementById("resultado").innerHTML = rValue;         
      }
  
  </script>
</head>
<body>
  <form id="form1" runat="server">
    <div>
  

     
      <input type="text"  ID="busca" onkeyup="Buscar()" />
      <br />
      <span id="resultado" runat="server"></span>
    </div>
  </form>
</body>
</html>




No código acima, adicionei dois controles, um textbox(busca) e um span(resultado).

No controle textbox eu coloquei o evento onkeyup para acionar a função Buscar() que é um Script. Essa função Buscar irá capturar o texto digitado no textbox e chamar o método CallServer passando essa informação.

abaixo o código C#:


using System;
using System.Configuration;
using System.Web;
using System.Linq;
using System.Collections.Generic;

namespace callback
{
    public partial class _default : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
    {

        protected String returnValue;
        protected void Page_Load(object sender, EventArgs e)
        { 
            Page.ClientScript.RegisterClientScriptBlock(this.GetType()
                , "CallServer",
                "function CallServer(arg, context) { " + Page.ClientScript.GetCallbackEventReference(this, "arg", "Retorno", "context") + ";}"
                , true);

        }
        public void RaiseCallbackEvent(String eventArgument)
        {
            if (eventArgument != "")
            {
                List<string> usuarios = new List<string>();

                usuarios.Add("Bruce Lee");
                usuarios.Add("Carmem Miranda");
                usuarios.Add("Castro Alves");
                usuarios.Add("Cecília Meireles");
                usuarios.Add("Clarice Lispector");
                usuarios.Add("Elvis Presley");
                usuarios.Add("Greta Garbo");
                usuarios.Add("Jorge Amado");
                usuarios.Add("Machado de Assis");
                usuarios.Add("Monteiro Lobato");
                usuarios.Add("Neil Armstrong");
                usuarios.Add("Thomas Edson");
                usuarios.Add("Tom Jobim");

                var resultados = from r in usuarios where r.Contains(eventArgument) select r;
               
                foreach (var item in resultados)
                {
                    returnValue += item+ "<br>";
                }
              
                if (returnValue == "" || returnValue == null)
                    returnValue = "Não localizamos o usuário informado";
               
            }

        }
        public String GetCallbackResult()
        {
            return returnValue;
        }
    }

}



Eu criei um List de string com o nome de usuários e adicionei alguns nomes.

Quando pressionamos uma tecla no banco "Busca" o evento Buscar() é invocado chamando acionando a função RaiseCallbackEvent  essa função irá buscar no List usuarios e retornar o valor para o navegador.



Ao executar temos o seguinte resultado:
Digitando um carácter:



o retorno é de todos os usuários que possua a letra C e seu nome. 


o legal de utilizar o Callback é não ter que recarregar a página só por conta de uma informação.



:)




segunda-feira, 27 de maio de 2013

LINQ to Entities

Utilizar LINQ to SQL é fácil,  mas só funciona com banco de dados MS-SQL.  

E se minha necessidade for utilizar o MySQL como banco de dados? Nesse caso teremos que utilizar o LINQ to Entities. O conceito é o mesmo e funciona para qualquer banco de dados.
Nesse caso eu vou utilizar o MySQL 5. 5.0.45.


Criei uma tabela com a seguinte estrutura:

Onde a coluna id  é por padrão incrementada 1 a 1.

Já no Visual Studio, precisamos adicionar uma conexão apontando para o MySQL.
Clique na guia Server Explorer e clique em adicionar conexão.  A janela a seguir irá aparecer:

Escolha MySQL e clique em ok.


Preencha os campos conforme seu banco de dados. No meu caso o nome do banco de dados é Projeto e esta localizada no Localhost. Vou usar o usuário root para acessar.

Após criar a conexão, é necessário adicionar o item ADO.NET Entity Data Model, como abaixo . Vou nomear o arquivo como Banco.edmx e clicar em Add. 



A janela a seguir será apresentada, escolha a opção “Generate from database”  e clique em Next.
Escolha a conexão para o banco de dados. E clique em Next.
Será apresentada a janela a seguir, nessa janela podemos escolher as entidades que vamos utilizar. No meu caso, somente a entidade usuário. Clique em Finish


Pronto, o mapeamento já foi feito e podemos trabalhar com a entidade criada.
Para inserir um registro faremos da seguinte maneira:
Banco bd = new Banco();//Representa o contexto do banco de dados

usuario u = new usuario();
u.nome = "Celso Zequim";
u.email = "czequim@gmail.com";
bd.AddTousuario(u);
bd.SaveChanges();

Ao pressionar F5, podemos ver que o registro foi inserido no Banco de dados:

Para ler essa informação e exibir no console é simples:

var usuarios = from ur in bd.usuario orderby ur.nome select ur;
foreach (usuario usr in usuarios)
{
       Console.Write(usr.nome);
       Console.WriteLine();               
}
           
O resultado é o seguinte:

Simples... e funciona para qualquer banco de dados, como: MySQL, Oracle, Postgres, Firebird... etc. 


:D


terça-feira, 14 de maio de 2013

Excel - Importação de dados


Importar dados de um arquivo Excel é muito simples.

Esse método utiliza a biblioteca  Microsoft.Office.Interop.Excel, que é responsável por manipular arquivo do tipo excel.

Nesse exemplo, independe do número de pasta de trabalho que tenha o arquivo ele irá percorrer todas as pastas de trabalho.

  public void  LeArquivo(string Arquivo)
        {
           

            Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();

 //Cria um objeto do tipo WorkBook com todos os elementos do Excel.
        Workbook workBook = app.Workbooks.Open(Arquivo,
        Type.Missing, true, Type.Missing, Type.Missing,
        Type.Missing, Type.Missing, Type.Missing, Type.Missing,
        Type.Missing, Type.Missing, Type.Missing, Type.Missing,
        Type.Missing, Type.Missing);
          

            int numSheets = workBook.Sheets.Count;
            //esse loop vai percorrer todas as pastas de trabalho do excel.
            for (int sheetNum = 1; sheetNum < numSheets + 1; sheetNum++)
            {
                Worksheet sheet = (Worksheet)workBook.Sheets[sheetNum];
                int numColumns = sheet.Columns.Count;
                int numRows = sheet.Rows.Count;

              
                    Range excelRange = sheet.UsedRange;
                //Pega todo conteúdo de uma linha e transforma e um array de objetos.
                    object[,] Linha = (object[,])excelRange.get_Value(XlRangeValueDataType.xlRangeValueDefault);

                    List<string[]> Linhas = new List<string[]>();
                    int cont_ant = 0;
                //Percorre todas as dimensões do array linha para pegar o conteúdo de cada célula.
                    for (int i = 1; i <= Linha.GetUpperBound(0); i++)
                    {
                        if (i > cont_ant)
                        {
                            cont_ant = i;
                            //pega o total de células preenchidas na linha e cria um array com o número exato de dimensões.
                            string[] celulas = new string[Linha.GetUpperBound(1)];
                            //percorre todas as células atribuindo preenchendo o array.
                            for (int j = 1; j <= Linha.GetUpperBound(1); j++)
                            {
                                if (Linha[i, j] != null)
                                    celulas[j - 1] = Linha[i, j].ToString();
                            }
                           
                            Linhas.Add(celulas);


                        }
                    }
                   

                //Nesse momento o List de string "Linhas" tem todo conteúdo  da pasta de trabalho.


            }
workBook.Close();

           

        }

sexta-feira, 3 de maio de 2013

Relatório utilizando GridView x LINQ


Existem algumas formas de desenvolver relatórios utilizando ASP.Net.
  • Utilizado um grid para exibir as informações
  • Crystal reports: modelando um template com colunas, agrupamentos, sub grupos, etc.
  • Gráficos

No exemplo que vou demonstrar será utilizado o gridview.

No gridview é possível formatar as informações que serão exibidas através de css, criar um cabeçalho , rodapé e ordenação.

O Visual Studio já tem alguns templates pre definidos para montar um grid. Isso agiliza a desenvolvimento, caso você não entenda muito de css.

Na guia tools clique e arraste para tela o controle GridView. após feito isso clique no grid adicionado e vá até a guia propriedades.

altere a propriedade ID, no meu caso vou chamar de gdvCliente.

Por padrão a propriedade AutoGenerateColumns vem marcada como True. Essa propriedade irá criar o grid com todas as colunas do seu DataSource.

Agora vou definir um template, clique no grid e clique na seta que esta na lateral direita superior e clique em Auto Format. Como na imagem abaixo:


A janela abaixo irá aparecer e vou escolher o template Snowy Pine. 



Agora vamos ao código.

Eu inclui um arquivo do tipo LINQ to SQL, com o nome de Banco.dbml e arrastei para ele a tabela de clientes.
No arquivo Default.aspx.cs eu adicionei o seguinte código:

BancoDataContext bd = new BancoDataContext();
var resultado = from r in bd.Clientes orderby r.nome select { r.nome, r.email, r.telefone }; 
gdvCliente.DataSource = resultado;
gdvCliente.DataBind();

Basicamente fiz uma query selecionando todos os registros da tabela Cliente exibindo somente os campos “Nome”, “Email” e “Telefone”.

Informei que o DataSource do meu grid(“gdvCliente”) é o resultado dessa consulta.
E chamei o método DataBind(), que é responsável por carregar o grid com as informações do DataSource.

Veja o resultado:
Também é possível incluir alguns filtros, nesse exemplo vou adicionar os seguintes controles:
  • Label – titulo do filtro
  • TextBox – receberá o valor que fará o filtro – txtNome
  • Button – Executará o filtro - btnFiltrar

No evento onClick do botão Filtrar eu adicionei o seguinte código:



BancoDataContext bd = new BancoDataContext();
var resultado = from r in bd.Clientes where r.nome.Contains(txtNome.Text) orderby r.nome select new { r.nome, r.email, r.telefone };
gdvCliente.DataSource = resultado;
gdvCliente.DataBind();

Basicamente o código é o mesmo, a única diferença é a clausula where onde eu informei que o campo nome deve conter o valor filtrado.

Veja o resultado:




terça-feira, 30 de abril de 2013

LINQ x Stored Procedure

LINQ utiliza a Stored Procedure (SP) como sendo um métodos em seu contexto de dados.

No exemplo a seguir vou criar uma SP para listar todos os clientes com o nome Celso Zequim. veja o código:

CREATE PROCEDURE BuscaCliente      @nome varchar(255)     
     
AS
BEGIN
      SELECT * from Cliente where nome = @nome
END
 
No Visual Studio adicione um arquivo do tipo LINQ to SQL, no meu caso vou adicionar com o nome Banco.dbml.




Ao criar o arquivo, adicionei uma nova conexão em Server Explorer apontando para meu banco de dados de testes.  e naveguei até a pasta StoredProcedures


Clique e arraste a StoredProcedures para dentro do arquivo Banco.dbml.
o resultado será o seguitne:


Será adicionado um Método com o nome da SP.

No arquivo Program.cs é só chamar a SP:


   static void Main(string[] args)
   {
       BancoDataContext bd = new BancoDataContext();

  var resultado = bd.BuscaCliente("celso zequim");
  foreach (var r in resultado)
  {
 Console.Write(r.nome);
  }
  Console.ReadKey();

   }


Pressione F5 e veja o Resultado: