Arquivo da tag: C#

Retornar dados no formato JSON usando ASP.NET

Olá pessoal.

Com o advento das chamadas assíncronas diretamente do cliente ao servidor via Javascript, muitas vezes é necessário retornar ao cliente dados estruturados,  que pode ser uma estrutura XML, uma simples string separada por um caractere especial, ou ainda no formato JSON.

Uma boa opção devido sua padronização e facilidade de manipulação é o formato JSON.

Serializar um objeto que é uma instância de uma classe para o formato JSON no C# é bem simples. O problema é quando queremos serializar dados que não representam um objeto de instancia de classe. Neste caso, a técnica mais comum é concatenar strings formando a estrutura desejada (já fiz muito isso), além de complicar uma futura manutenção, não é elegante.

No C# podemos criar objetos de tipo anônimos (anonymous types), definir sua estrutura e dados, e depois serializar para o formato  JSON enviando tudo  ao cliente.

Exemplo de criação de um vetor de tipo de anônimo e com dados:

var vetorAnonimo = new object[] { new { nome = "nome 1", id = 1 },
                                  new { nome = "nome 2", id = 2 }};

Com o objeto anônimo definido e carregado é possível fazer sua serialização para enviar ao cliente:

using System.Web.Script.Serialization;

JavaScriptSerializer js = new JavaScriptSerializer();
string strJson = js.Serialize(vetorAnonimo);

Pronto. É só devolver a variável strJson para a função de callback no Javascript/JQuery e manipular o retorno.

Veja como chega no cliente o vetor serializado, uma string estruturada no formato JSON. Lindo!!!

[{"nome":"nome 1","id":1},{"nome":"nome 2","id":2}]

Este post teve ajuda do @victorvhpg ninja do JQuery.

1º DojoPrudente

Olá pessoal.

Na noite de hoje (09/11) aconteceu o primeiro @dojoprudente. Foi um momento de troca de conhecimento, aprimoramento e muita diversão na sede da Activit. Imaginem só, um monte de programadores tentando resolver usando TDD um algoritmo para retornar os possíveis anagramas de uma palavra. Que vergonha, não conseguimos resolver (mas no primeiro pode hehehe).

Assim  que a equipe da tiprudente  publicar as fotos coloco o link aqui.

E até o próximo.

Validar a quantidade de caracteres num TextBox MultiLine (TextArea)

Sabemos que para transformar o ServerControl TextBox em TextArea temos que mudar sua propriedade TextMode para o valor MultiLine. Também sabemos que via HTML não é possível limitar o tamanho de um TextArea por meio do MaxLength como é feito num Input Text. Isso pode ser contornado com o uso de Javascript.

Usando o controle ASP.NET RegularExpressionValidator e a expressão regular ^.[sS]{0,500}$, é possível validar a quantidade de caracteres inseridas num TextBox MultiLine (TextArea). Na expressão acima, o valor 500 é a quantidade máxima de caracteres que desejamos no TextBox MultiLine (TextArea).

<asp:TextBox ID="TextBox1" runat="server" Height="93px" TextMode="MultiLine" Width="381px"></asp:TextBox>
<br />
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="TextBox1"
  ErrorMessage="Ultrapassou 500 caracteres." ValidationExpression="^.[sS]{0,500}$">
</asp:RegularExpressionValidator>

Bom proveito.

Definindo classes em C# – Parte 4

Herança

Herança é um tipo de relacionamento/associação entre classes. É usada quando é necessário que uma determinada classe tenha todas as características de outra classe com algumas modificações em seu comportamento, ou mesmo algumas funcionalidades adicionais.

As palavras generelização e especialização fazem parte do conceito de Herança. Uma classe “mais genérica” (generelização) pode gerar uma nova classe que herda suas características, mas permitindo modificações e novas implementações, ou seja, a nova classe é uma especialização da classe genérica.

Um exemplo tradicional usado para explicar o conceito de herança é a definição das classes Pessoa, PessoaFisica e PessoaJuridica. A classe Pessoa é genérica, e contém atributos, métodos e propriedades que podem representar qualquer pessoa. Já as classes PessoaFisica e PessoaJuridica respectivamente representam uma características para uma pessoa física e pessoa jurídica, e são classes especializadas, pois especializam a classe Pessoa.

Em C# uma relação de Herança é implementada com o uso do símbolo “:” (dois pontos) na definição da classe.

Classe genérica (Pessoa).

public class Pessoa
{
    int _id;
    DateTime _dataCadastro;

    public int Id
    {
        get { return this._id; }
        set { this._id = value; }
    }

    public DateTime DataCadastro
    {
        get { return _dataCadastro; }
        set { _dataCadastro = value; }
    }

    public int GerarId()
    {
        throw new NotImplementedException();
    }
}

Classes especializadas PessoaFisica e PessoaJuridica.

public class PessoaFisica: Pessoa
{
    string _nome;
    DateTime _dataNascimento;
    string _cpf;

    public string Nome
    {
        get { return _nome; }
        set { _nome = value; }
    }

    public DateTime DataNascimento
    {
        get { return _dataNascimento; }
        set { _dataNascimento = value; }
    }

    public PessoaFisica(int id, DateTime dataCadastro, string nome, string cpf)
    {
        base.Id = id;
        base.DataCadastro = dataCadastro;
        this._cpf = cpf;
        this._nome = nome;
    }

    public PessoaFisica EncontrarPorCpf(string cpf)
    {
        throw new NotImplementedException();
    }
}

public class PessoaJuridica : Pessoa
{
    string _cnpj;
    string _razaoSocial;

    public string Cnpj
    {
        get { return _cnpj; }
        set { _cnpj = value; }
    }

    public string RazaoSocial
    {
        get { return _razaoSocial; }
        set { _razaoSocial = value; }
    }

    public PessoaJuridica(int id, DateTime dataCadastro, string cnpj, string razaoSocial)
    {
        base.Id = id;
        base.DataCadastro = dataCadastro;
        this._cnpj = cnpj;
        this._razaoSocial = razaoSocial;
    }

    public PessoaJuridica EncontrarPorCnpj(string cnpj)
    {
        throw new NotImplementedException();
    }
}

Graficamente a Herança no Diagrama de Classe tem o seguinte aspecto.

Como é possível perceber no exemplo acima, as classes especializadas tem acesso aos membros implementados na classe genérica atráves da palavra reservada base.

Métodos Virtuais

A classe genérica pode oferecer métodos que podem ser reescritos nas classes especializadas. Isso é possível quando um método é decorado com a palavra reservada virtual. Para reescrevê-lo na classe especializada, o método deve ser decorado com a palavra reservada override.

public class Pessoa
{
    ...

    public virtual Pessoa EncontarPorId(int id)
    {
        throw new NotImplementedException();
    }
}

public class PessoaJuridica : Pessoa
{
    ...

    public override Pessoa EncontarPorId(int id)
    {
        //Nova implementação
    }
}

public class PessoaFisica : Pessoa
{
    ...

    public override Pessoa EncontarPorId(int id)
    {
        //Nova implementação
    }
}

Por enquanto é só isso. Até o próximo.

Definindo classes em C# – Parte 3

Sobrecarga de Métodos (overloading)

A linguagem C# permite que métodos diferentes possuam o mesmo nome. Essa implementação é possível pois a assinatura dos métodos são diferentes. Uma assinatura é formada pelo nome do método e sua lista de parâmetros.

Geralmente o uso da sobrecarga está associada quando uma método precisa de uma série de métodos que adotem parâmetros diferentes, mas que fazem conceitualmente a mesma coisa, como por exemplo quando necessitamos ter parâmetros opcionais, diferentes tipos de entrada ou diferentes tipos de saídas (através dos parâmetros).

public void FaçoAlgumaCoisa()
{
}

public void FaçoAlgumaCoisa(int p1)
{
}

public void FaçoAlgumaCoisa(int p1, int p2)
{
}

public void FaçoAlgumaCoisa(string p1, int p2)
{
}

public void FaçoAlgumaCoisa(int p1, int p2, out int p3)
{
}

A invocação dos metódos acontece de forma tradicional. O compilador da linguagem chamará o método correto conforme a lista dos parâmetos.

FaçoAlgumaCoisa();
FaçoAlgumaCoisa(1);
FaçoAlgumaCoisa(1, 2);
FaçoAlgumaCoisa("1", 2);

int x;
FaçoAlgumaCoisa(1,2, out x);

Quando usamos o VisualStudio o autocomplete dá um força mostrando as sobrecargas do método.

Até mais.

Definindo classes em C# – Parte 2

Métodos Estáticos

No post anterior vimos que uma classe pode ser instanciada, e que cada instância é chamada de objeto. Cada objeto é independente, ou seja, instâncias da mesma classe “não se conhecem”, não compartilham dados.

Pessoa pessoa1 = new Pessoa();
Pessoa pessoa2 = new Pessoa(1,"Filogonio Silva",dataNasc);
Pessoa pessoa3 = new Pessoa(2,"Fippildo Silva",dataNasc);

No código acima, as instâncias (ou objetos) da classe Pessoa, pessoa1, pessoa2 e pessoa3 contêm seus próprios dados. Os membros criados na classe somente podem ser vistos por seus respectivos objetos, pois foram definidos como membros de objetos. Há caso que esse não é o comportamento desejado. É possível definir membros da classe, que são chamados de membros estáticos, não sendo necessário instanciar a classe para usá-los.

A declaração de um membro estático se dá através da palavra reservada static. Um membro estático está disponível desde o momento que o programa é executado.

O código abaixo exemplifica a definição de um atributo estático e sua respectiva propriedade (somente get) para retorna seu valor.

//atributo estático
static int _tamanhoNome = 100;

//propriedade estática
public static int TamanhoNome
{
    get { return _tamanhoNome; }
}

Como dito anteriormente, um membro estático existe deste a execução do programa, não sendo necessária a instanciação da classe, basta acessar a classe e invocar o membro estático.

Pessoa pessoa1 = new Pessoa();
Pessoa pessoa2 = new Pessoa(1, "Filogonio Silva", dataNasc);
Pessoa pessoa3 = new Pessoa(2, "Fippildo Silva", dataNasc);

//Uso de propriedade estática.
Response.Write(Pessoa.TamanhoNome);

Para finalizar, é importante destacar que um método estático não pode acessar outros membros da classe que não sejam estáticos.

Até o próximo…

Definindo classes em C# – Parte 1

Olá pessoal.

A ideia deste post não é mostrar o conceito de classe (ou mesmo da Orientação a Objetos), e sim como criar classes na linguagem C#.

Numa aplicação desenvolvida com uma linguagem orientada a objetos o uso de classe é bem comum. Mesmo aplicações pequenas em C# necessitam da elaboração de uma ou mais classes, cada uma com suas propriedades e métodos usados para executar as tarefas relativas ao objeto.

Mas o que é uma classe? Uma classe pode ser definida como um gabarito de um objeto. Acho que agora piorou, certo?

Primeiro vamos entender o que é um objeto. Um objeto na programação OO é qualquer coisa que seja um único item que se queira identificar num programa, como por exemplo uma pessoa, um carro, um computador, uma caneta, um usuário, etc. Mas o que seria a classe? A classe define como esse objeto deve ser, por isso é um gabarito de um objeto.

A classe gera o objeto de acordo com sua estrutura, e esse processo de criação do objeto é chamado de instanciação da classe.

Em C#, podemos ter dentro de uma classe os seguintes membros: atributos, construtores, destrutores, domínios, métodos, propriedades, indexadores, delegates, eventos e classe aninhadas. As classes são declaradas usando a palavra reservada class e precedida de um modificador de acesso, conforme mostrado no exemplo a seguir

public class Pessoa
{
}

Os modificadores de acesso dizem ao compilador da linguagem como classe será acessada externamente. Os moficadores são para classe são:

public: Permite que a classe seja acessada por qualquer outra classe.
selead: Não permite que a classe seja herdada.
partial: Permite que a classe tenha seu escopo dividido em vários arquivos.
static: Especifica que a classe somente tem membros estáticos. Não pode ser instanciada.
abstract: Define moldes para classes filhas. Não pode ser instanciada.

Atributos, Métodos, Propriedades e Construtores

Atributos

Atributo são declarados dentro da classe e são os elementos que definem sua estrutura. São como variáveis da classe.

public class Pessoa
{
    int _id;
    string _nome;
    DateTime _dataNascimento;
}

Métodos

Os métodos são as ações que a classe ou uma instância da classe realização. A declaração de um método contempla um modificador de acesso, um tipo de retorno, o nome do método e opcionalmente parâmetros.

public class Pessoa
{
    int _id;
    string _nome;
    DateTime _dataNascimento;

    public int CalcularIdade()
    {
        int idade = DateTime.Now.Year - this._dataNascimento.Year;
        return (idade);
    }

    public int CalcularIdade(DateTime dataReferencia)
    {
        int idade = dataReferencia.Year - this._dataNascimento.Year;
        return (idade);
    }
}

É possível ter métodos com o mesmos nomes, sendo suas assinaturas diferentes, isso é chamado de sobrecarga de métodos. E ainda é possível criar métodos que não tenham um retorno específico usando a palavra reservada void.

protected void FazAlgumaCoisa()
{
    //Faz alguma coisa e não retorna...
}

Um método é classificado em “Contexto de Ação”, quando é centrado nos processos e atividades realizadas. Ex.: impressão de um cabeçalho padrão, mudança de configuração de tela, mudança de um status, etc. Normalmente não possuem retorno. É classificado como “Contexto de Resultado”, quando o objetivo é calcular ou obter algum valor em especial. Ex.: validação, resultado de um cálculo, etc. Normalmente retorna um valor.

Propriedades

Algumas linguagens de programação implementam o conceito Propriedades em suas características de Orientação a Objetos. Alguns puristas não concordam com uso, pois alegam que fere alguns conceitos tradicionais da OO.

A linguagem C# promove o uso de Propriedades, que são métodos que protegem (encapsulam) o acesso a membros da classe, ou seja, separa os elementos visíveis de um objeto dos invisíveis. As propriedades podem ser substituidas pelo clássico uso dos métodos set e get.

public class Pessoa
{
    int _id;

    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }

    string _nome;

    public string Nome
    {
        get { return _nome; }
        set { _nome = value; }
    }

    DateTime _dataNascimento;

    public DateTime DataNascimento
    {
        get { return _dataNascimento; }
        set { _dataNascimento = value; }
    }
}

Na classe acima todos atributos foram encapsulados por propriedades, por exemplo o atributo int _id foi encapsulado pela propriedade public int Id. A propriedade Id poderia ter sido substituída sem problemas por um método set e get.

int _id;

public int GetId
{
    return _id;
}

public int SetId
{
    _id = value;
}

Modificações de acesso para atributos, métodos e propriedades

Atributos, métodos e propriedades necessitam de moficadores de acesso. Os principais para estes recursos são:

Public: Permite que os membros das classes sejam acessados por qualquer outro escopo
Protected: Permite que membros sejam usados apenas pela classe que o contém e permite que estes sejam “herdados” para classes derivadas da original.
Private: O membro é de uso exclusivo da classe onde é declarado.
Internal: Permite acesso somente por classes do mesmo assemblie.
Static: Permite acesso, sem necessidade do objeto ser instanciado.
Abstract: São métodos de classes Abstract que não possuem implementação (sem codificação).
Virtual: Permite que os métodos sejam sobrescritos por classes filhas.
Readonly:Limita acesso a somente leitura aos atributos da classe

Construtores

As classes podem apresentar métodos de inicialização chamados de construtores. São métodos responsáveis por inicializar os objetos das classes (instâncias das classes). E são identificados por um método com o mesmo nome da classe e sem retorno.

public class Pessoa
{
    public Pessoa()
    {

    }

    public Pessoa(int id, string nome, DateTime dataNascimento)
    {
        _id = id;
        _nome = nome;
        _dataNascimento = dataNascimento;

    }
    ...

Acima foram criados dois construtores, o primeiro não faz nada (construtor padrão) e o segundo recebendo valores para inicializar os atributos da classe.

Instanciando classes

A instanciação da classe ocorre através da palavra reservada new. Se uma classe é estática (static) ela tem um comportamente diferente, não sendo necessário fazer sua instanciação para uso.

Pessoa pessoa1 = new Pessoa();
Pessoa pessoa2 = new Pessoa(1,"Filogonio Silva",dataNasc);
Pessoa pessoa3 = new Pessoa(2,"Fippildo Silva",dataNasc);

Existe outros conceitos (mais avançados) envolvendo classes. Aqui é só um “aquece”.

Até mais.

DataList com paginação

O controle DataList do ASP.NET é uma mão da roda para exibir listagem de dados usando um layout menos “tabular”. Infelizmente o DataList não possui de forma nativa (como no GridView, FormView e DetailsView) uma opção para definir páginas de dados (paginação). Mas isso não é problema, pois podemos implementar “na unha” esse recurso.

Vamos lá.

Neste exemplo usei a tabela Products do banco de dados de exemplo Northwind que acompanha o SQL Server Express 2008. E a paginação é de 10 registros por página.

A seguir segue o código de definição de um DataList para listagem de registros vindos da tabela Products. Observe que adicionei ao FooterTemplate dois LinkButton para representar a navegação da paginação.

<asp:DataList ID="DataList1" runat="server">
    <FooterTemplate>
        [<asp:LinkButton ID="lkbtnAnterior" runat="server" onclick="lkbtnAnterior_Click"><< Anterior</asp:LinkButton>]
        [<asp:LinkButton ID="lkbtnProximo" runat="server"  onclick="lkbtnProximo_Click">Próximo >></asp:LinkButton>]
    </FooterTemplate>
    <ItemTemplate>
        ProductID: <%#DataBinder.Eval(Container.DataItem, "ProductID").ToString()%>
        <br />
        ProductName: <%#DataBinder.Eval(Container.DataItem, "ProductName").ToString()%>
        <br />
        UnitPrice: <%#DataBinder.Eval(Container.DataItem, "UnitPrice", "{0:C}").ToString()%>
        <hr />
    </ItemTemplate>
</asp:DataList>

O código C# abaixo representa um método criado na página para tratar a listagem dos dados, inclusive por fazer a paginação. O código por ser adaptado para qualquer realidade.

protected void ListarDados(string tipo)
{
    int tamanhoPagina = 10;
    int registroInicio = 0;

    if (ViewState["registroInicio"] != null)
        registroInicio = (int)ViewState["registroInicio"];

    if (tipo == "proximo")
        registroInicio += tamanhoPagina;
    else if (tipo == "anterior")
        registroInicio -= tamanhoPagina;

    if (registroInicio < 0)
        registroInicio = 0;

    SqlConnection con = new SqlConnection(@"Data Source=localhostSQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True");
    SqlCommand cmd = con.CreateCommand();
    cmd.CommandText = "SELECT PRODUCTID, PRODUCTNAME, UNITPRICE FROM PRODUCTS ";

    con.Open();

    SqlDataAdapter da = new SqlDataAdapter();
    da.SelectCommand = cmd;
    DataTable dt = new DataTable();

    //Preenchendo o DataTable com a quantidade de registro que se pretende mostrar.
    da.Fill(registroInicio, tamanhoPagina, dt);

    //Tratando o fim da navegação
    if (tipo == "proximo" && dt.Rows.Count == 0 && registroInicio > 0)
    {
        registroInicio -= tamanhoPagina;
        da.Fill(registroInicio, tamanhoPagina, dt);
    }

    DataList1.DataSource = dt;
    DataList1.DataBind();
    con.Close();

    ViewState.Add("registroInicio", registroInicio);
}

O código abaixo implementa os botões de navegação.

protected void lkbtnAnterior_Click(object sender, EventArgs e)
{
    ListarDados("anterior");
}

protected void lkbtnProximo_Click(object sender, EventArgs e)
{
    ListarDados("proximo");
}

Para listar os dados e mostrar a primeira página, chame o método ListarDados sem informar as opções de navegação. Desta forma:


    ListarDados("");

Baixe aqui o exemplo.

Para deixar mais eficiente o recurso de paginação, recursos do próprio banco de dados como a funções TOP, FIRST, LAST e etc podem ser utilizados.

Crystal Reports: ToNumber() vs VAL():

Após horas tentando achar uma solução para o erro “[COMException (0x80041019): A sequência de caracteres não é numérica”, numa formula feita num relatório do Crystal Report, eis a solução. Ufa!!!!

Muitas formulas construídas no Crystal Report usam a função ToNumber() para converter texto para números. Esta função  pode gerar erros quando encontra alguma sequência de carateres de pontuação ou símbolos.
A função VAL() é mais tolerante ao encontrar certos caracteres, assim conseguindo fazer a conversão desejada.

Mais detalhes no artigo original em http://kenhamady.com/cru/archives/81

Concatenação de string (C#)

A concateção de strings é algo muito comum no dia-a-dia. Normalmente fazemos a conteção da seguinte forma:

string str = “linha 1″ +
” linha 2  ” +
” linha 3 “;

Isso é bem comum quando temos instruções SQL embutidas na linguagem.

E que tal fazer a concateção assim:

string str = @”linha 1
linha 2
linha 3“;

Observer o caracter @ antecedendo a string. E ele que faz toda a diferença. Muito mais prático, não?