Encodings e charsets em Asp.NET

Geralmente não precisamos nos preocupar com os Encodings em uma aplicação em .NET. Isto porque ao desenvolvermos um sistema .NET, utilizamos ferramentas uniformizadas, afinal, elas provêm de uma mesma fabricante: Microsoft.

(Já quando desenvolvemos soluções LAMP, ou mesmo WAMP, nosso cuidado precisa aumentar e muito.)

O fato é que o framework Asp.NET provê uma facilidade incrível para lidar com esta questão que sempre perturba os desenvolvedores. Mesmo no momento de se gravar ou ler arquivos do sistema de arquivos o encoding é tratada de forma automática.

A regra então é: não se preocupe com isto, a menos que algo dê errado e surja algum caractere estranho. E é claro que algo sempre dará errado.

Bom, então quando precisamos mudar o encoding de alguma string em Asp.NET? Simples:

Encoding.UTF8.GetString(Encoding.GetEncoding("iso8859-1").GetBytes("Texto com acentuação e caracteres não-ANSI"));

A código acima toma uma string em ISO-8859-1 e tranforma-a em uma no formato UTF-8.

Posted in programação, software, web | Tagged , | 2 Comments

Google Tasks Desktop

Os usuário do Gmail já devem conhecer o Google Tasks. Se não conhecem, basta habilitarem o dito cujo no Google Labs, e, de dentro das funções do Labs, habilitarem finalmente o Google Tasks.

Google Tasks

Se você possui mais de um monitor, deve saber como desktop widgets são úteis. Informação disponível com um rápido olhar.

Para conseguir transformar o Google Tasks em um widget de desktop, ou melhor, em um aplicativo desktop, você vai precisar do Google Chrome. Dentre algumas maneiras de se fazer isto, achei esta a mais simples:

Posted in software, web | Tagged , | 1 Comment

Ext JS

O Ext (http://extjs.com) trata-se de um framework JavaScript para criar objetos de interface com o usuário, ou UI gadgets, como grids, trees, layouts em tabs e muito mais.

O legal é que os elementos criados com o ExtJS não ficam devendo nada às aplicações web que estamos acostumados a ver nos serviços do Google, Yahoo e Microsoft, sejam na funcionalidade, seja no visual.

Sua licença é dual: LGPL ou comercial, com preços iniciando em USD $289. Infelizmente nem todos os desenvolvedores precisam/querem/suportam JavaScript.  Se for o caso recomendo ficar longe do ExtJS.
Mas caso queira se aventurar no mundo ExtJS, nada melhor que baixar o dito cujo e dar uma olhada nos samples. Quem sabe não coloco um tutorial bem simples por aqui também…

Padrões de projeto

Para entender o funcionamento da API do Ext é muito importante ter conhecimento sobre os chamados padrões de projeto, ou design patterns. As referências nesta área são o livro do Gang of Four (WikiPedia:Design_Patterns) e o site C2. Este último também é conhecido por ser o primeiro wiki do mundo.

O básico para você não se perder é entender que existem componentes Ext de apresentação e outros que fornecem dados. Os de apresentação são apresentados (não diga!) no navegador, requisitando dados aos componentes que fornecem dados (interessante…).

Um exemplo disto é um combobox, que podemos separar em algumas partes:

  • um elemento DOM que servirá de contêiner para o combobox, um <div>, por exemplo;
  • o componente Ext.form.ComboBox;
  • um componente para os dados a serem apresentados pelo combobox.
Posted in programação, web | Tagged , , , | 2 Comments

Type “casting” no Javascript

O Javascript possui uma característica que pode incomodar quem está acostumado à linguagens como C, Java, C++: ele é fracamente dinamicamente tipificado.
Mas a possibilidade de modificar qual o tipo de uma variável é  útil.  Esta modificação de tipo é o casting.

Podemos efetuar um casting de um float para int através da função parseInt:

b = 3;
c = 2;
a_int   = parseInt(b/c); //a_int contém 1
a_float = b/c; //a_float contém 1.5

E o contrário também, através do parseFloat.

Note que essas funções, na verdade, efetuam o parse do parâmetro de entrada, que pode ser uma string, devolvendo o valor final no tipo identificado por seu nome.

Mais info: W3Schools:parseInt(), W3Schools:parseFloat()

Posted in programação, web | Tagged | Leave a comment

Quirks mode – que diabo é isto?

Quirks mode (Wikipedia:Quirks_mode) é um modo de compatibilidade existente nos browsers, para que renderizem corretamente página antigas, escritas em uma época em que o CSS e o modelo de separação entre conteúdo e apresentação não estava disseminado.

Ou seja, páginas que foram escritas tendo em vista seu funcionamento em navegadores da época (Internet Explorer 4.x, Netscape Navigator 4.x), mas não seguiam os padrões ditados pela W3C, precisam rodar no quirks mode nos browsers modernos, a fim de manterem as mesmas características de antes.

Como abrir uma página em quirks mode?
Simples. Basta deixar de colocar a tag indicando o DOCTYPE logo no início do código da página. Como esta, retirada desta mesma página:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html>


E para que a página funcione em standard mode é só incluir o doctype acima.
Inclua sempre e use o standard mode. Evita MUITAS dores de cabeça.

Posted in web | Tagged , | Leave a comment

Hash com MD5 de uma string vazia

MD5 é um algoritmo que calcula o hash de determinado string, muito usado para encriptar senhas. Assim, ao guardar uma senha do tipo “The quick brown fox jumps over the lazy dog” no banco de dados, o que realmente é gravado é:

MD5("The quick brown fox jumps over the lazy dog") = 9e107d9d372bb6826bd81d3542a419d6

E na próxima vez que você digitar a senha, é calculado o hash MD5 de sua senha e comparado com o valor armazenado no banco.

Agora a parte útil. O hash MD5 de uma string vazia é:

MD5("") = d41d8cd98f00b204e9800998ecf8427e

Uma mão na roda cso seja preciso resetar uma senha esquecida e você tenha acesso ao banco de dados.

Mas, se o sistema validar o campo referente à senha, vai ser preciso digitar algo. Uma boa é calcular o MD5 de alguma string não vazia qualquer via terminal, ou então utilizar alguma ferramenta online.

Atenção: Isto não vai funcionar se o hash estiver com sal!

Posted in programação | Tagged | Leave a comment

Hash com tempero

saltPara armazenarmos senhas em algum lugar, seja em uma lista em um arquivo texto, seja em uma tabela no banco de dados, é prática comum apenas guardarmos o hash da senha.

Mas o que é um hash? Para a necessidade descrita acima basta saber que o hash é uma forma de transformar um texto qualquer em uma seqüência de caracteres de comprimento fixo, de tal forma que é quase impossível gerarmos duas seqüências iguais para dois textos de entrada diferentes. Para isto utilizamos a chamada função de hash.

Existem diversos algoritmos que tentam resolver este problema, sendo os mais conhecidos, pelo menos por mim, o MD5 e o SHA1.

Vejamos um exemplo. Utilizando o algoritmo MD5, o hash gerado pela seqüência “teste do hash” é 92c2cafeb0c5fb58998be977b7deffbb.

Para calcular o hash visite a página http://www.fileformat.info/tool/hash.htm.

Voltando às senhas, após guardar este hash no banco de dados, como fazemos para conferir a senha posteriormente? É simples, Basta tomarmos o texto de entrada, calcular seu hash e comparar os dois: o gerado no momento com o valor armazenado.

Por exemplo: tenho em meu BD o texto 92c2cafeb0c5fb58998be977b7deffbb.
Alguém insere “blablabla” na caixa de texto de minha página.
Eu calculo o hash MD5 de “blablabla” e comparo com o valor que tenho guardado:

guardado no BD:  92c2cafeb0c5fb58998be977b7deffbb
“blablabla”:  1a36591bceec49c832079e270d7e8b73

Os valores calculados são diferentes. Então blablabla não é a senha. Note que não preciso saber qual a senha.  Só seu hash.

O sal, por favor!

Existe um problema na abordagem acima. Caso alguém obtenha acesso indevido às consultas no banco de dados, pode utilizar o ataque de dicionário para obter as senhas. Isto é, tomando palavras comuns, pode-se gerar seus hashes e verificar se no banco existem hashes iguais a este gerado.

O problema piora se existirem senhas iguais para usuários diferentes. Eles terão valores de hash iguais guardados no banco de dados. Para evitar este problema e dificultar um pouco (pois é, só um pouco) a vida do atacante existe o sal. Devemos salgar o hash (temperá-lo com sal, ou hash salting).

Esta técnica consiste em criarmos uma seqüência aleatória de caracteres, que chamamos de sal, e anexarmos este valor ao texto da senha, para só depois calcularmos seu hash. Isto diminui bastante a chance de termos valores iguais de hash armazenados.

Como o sal é gerado aleatoriamente, precisamos guardá-lo para que seja possível compararmos senhas no futuro. É prática comum apenas concatenarmos o sal com o hash antes de armazenarmos seu valor.

Receitas

Hash salgado:

  • tomar o texto de entrada, ou a senha;
  • pegar o sal;
  • salgar a senha;
  • calcular o hash da senha salgada;
  • salgar o hash;
  • guardar o hash salgado.

Dizem que um hash salgado dura mais que um sem sal!
E para conferir um valor contra o hash armazenado:

  • pegar o hash armazenado e extrair o sal;
  • tomar o texto de entrada e salgá-lo com o sal extraído anteriormente;
  • calcular o hash do texto salgado;
  • salgar o hash calculado;
  • comparar o hash calculado com o armazenado.
Posted in programação | Tagged | Leave a comment

Boas práticas em Linq To Sql

Estou tentando descobrir uma boa maneira de lidar com o Linq To Sql. Determinar um padrão que seja robusto e flexível no uso desta ferramenta. Mas para se usar uma ferramenta da melhor maneira possível é preciso conhecê-la!

Funcionamento

Não colocarei aqui instruções para uso básico do Linq, mesmo porque já existem excelentes tutoriais por aí (aos interessados na tecnologia, recomendo assinar o feed do Scott Guthrie).

Para o Linq To Sql funcionar devemos criar um arquivo de classes Linq to Sql (dbml). Este XML serve de metacódigo, utilizado para criar dinamicamente várias classes de forma automatizada. Dentre estas classes é criada também um
Unit of Work e um Data gateway em um único objeto: o DataContext.

O DataContext é responsável por guardar/conter/seguir as alterações em todos objetos Linq (Unit of Work) e por conversar com o banco de dados (Data Gateway).

É através do DataContext que conversamos com o banco de dados. E o DataContext gosta de conversar sobre objetos.

Imaginemos uma tabela Abacaxi em nosso banco de dados, com as colunas id, responsavel, tarefa e datalimite.

Tabela Abacaxi

Mapeando através do dbml, cria-se a classe Abacaxi no sistema, com as seguintes propriedades: id, responsavel, tarefa e datalimite.

Abacaxi Linq Object

Simples não? O Linq To Sql te dá o Abacaxi, pronto para descascar.

Problemas

Mesmo após a curva inicial de aprendizado, em que devemos nos acostumar com a sintaxe Linq, e a reaprender a escrever  consultas triviais em SQL, existem outros problemas que permanecem.

Cada objeto Linq To Sql se refere à uma entrada em uma tabela de banco de dados. Como ele serve primariamente para transportar dados, não contendo métodos próprios,  podemos chamá-lo de DTO (Data Transfer Object).

Este DTO é de díficil utilização, quando desconectados. Digo, se você consulta a tabela Abacaxi através do Linq To Sql, você consegue uma monte de objetos Abacaxi’s.

Tome um destes objetos Abacaxis. Vamos batizá-lo de abac. Eu pego o abac e jogo o DataContext que o criou fora. Atualizo o abac. Instancio um novo DataContext, do mesmo tipo que o anterior.

Este abac deve ser conectado a um DataContext de uma maneira muito complicada. Muito mais complicada do que deveria.

Há quem diga que, por esta e outras,  o Linq To Sql não está pronto para uma aplicação em  camadas (N-tier),  situação  atendida plenamente por ferramentas como o Hibernate.

Se mesmo assim você quser utilizar o Linq, já existe uma excelente discussão sobre as possibilidades de se arquitetar seu projeto com o uso do Linq To Sql em mente.

Meu uso

No projeto em que estou trabalhando, utilizamos o Linq To Sql sem muitas dores de cabeça. No momento é esta a arquitetura empregada:

  • Para cada subsistema, um DBML;
  • Para cada tabela, uma classe de negócios;
  • Para cada view no BD, uma classe correspondente (para cada coluna uma propriedade);
  • Cada objeto de negócios, uma instância do DataContext.

A classe de negócios acaba ficando bem parecida com uma DAL, com a importante diferença dela se utilizar do Linq To Sql para intermediar o acesso ao BD.

Segue o esqueleto da classe de negócios:

public class AbacaxiBLL: ITestableCrud, IDisposable
{
    protected ExemploDataContext dc;

    public AbacaxiBLL()
    {
        dc = new ExemploDataContext();
    }

    public Abacaxi Le(int id)
    {
        throw new NotImplementedException();
    }

    public Abacaxi Adiciona(Abacaxi obj)
    {
        throw new NotImplementedException();
    }

    public Abacaxi Atualiza(Abacaxi obj)
    {
        throw new NotImplementedException();
    }

    public void Exclui(int id)
    {
        throw new NotImplementedException();
    }

    public void Dispose()
    {
        throw new NotImplementedException();
    }
}

O corpo do método Adiciona fica assim então:

public Abacaxi Adiciona(Abacaxi obj)
{
    dc.Abacaxis.InsertOnSubmit(obj);
    dc.SubmitChanges();
    return obj;
}

Isto te dá a liberdade de operar com o objeto Abacaxi obj antes de inserí-lo no BD.

E eu sempre tomo o cuidado de implementar a interface IDisposable, o que te obriga a criar o seguinte método:

public void Dispose()
{
    dc.Dispose();
}

No final, o uso deste objeto de negócio é bem simples:

using (AbacaxiBLL bll = new AbacaxiBLL())
{
    Abacaxi a = new Abacaxi();
    a.responsavel = "Seiti Yamashiro";
    a.tarefa = "Criar um post sobre o Linq To Sql no blog seiti.eti.br";
    a.datalimite = new DateTime(2009, 5, 7);

    a = bll.Adiciona(a);
}

Aos DBAs de plantão, meus métodos nas classes de negócios seriam o equivalente às SPROCs no banco de dados, que cuidadriam de toda a manipulação de dados. O ganho é a organização de maior possibilidade de reutilizar e compartilhar código. E fica muito mais fácil de se versionar (Subversion, anyone?) isto!

Conclusão

Não tão robusto quanto um Hibernate, muito melhor que DataSets tipados. Fácil de aprender e usar, difícil de estabelecer uma arquitetura que satisfaça plenamente. Este é o Linq To Sql.

Posted in programação | Tagged , | 5 Comments

Fatos fundamentais que não devem ser esquecidos

O texto é de 2001, mas continua atualíssimo. Se as tecnologias mudam, os programadores, engenheiros, arquitetos e gerentes… esses não mudam não.

Pressure to achieve estimation targets is common and tends to cause programmers to skip good software process. This constitutes an absurd result done for an absurd reason.

Só por essa já vale dar uma lida. Muio mais pode ser encontrado em Frequently Forgotten Fundamental Facts about Software Engineering

Posted in programação | Tagged | Leave a comment

Compilando seu Web Application Project com o MSBuild

Programar em um IDE como o Visual Studio te dá muitas facilidades. O processo de compilação fica quase imperceptível para o desenvolvedor.

O problema surge no momento em que você quer algo diferente, como compilar versões distintas do código a partir do mesmo fonte, automatizar o build no servidor etc .

Para os que já usam Makefile ou o Ant, isto é trivial. Mas isto também é simples para os que usam o Visual Studio!

Vamos ver como construir um simples arquivo para o MSBuild compilar nosso projeto.

Primeiro é necessário que você possua o MSBuild instalado. Não se preocupe,  o Visual Studio 2008 já o instala .

E onde está o diabo do msbuild.exe? Aqui:

%windir%\Microsoft.NET\Framework\

Ou melhor,  execute (com as aspas!) o seguinte comando em um terminal:

"%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat"

Teste digitando msbuild.exe /help

Precisamos agora construir um makefile arquivo de instruções para o MSBuild, que chamarei de Makefile.proj:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build"
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
  ToolsVersion="3.5">
  <!-- aqui eu importo um projeto que já existe, contendo todos os
      arquivos e assemblies que fazem parte do processo de compilação-->
  <Import Project="MeuProjeto.csproj"/>
  <!-- aqui eu defino algumas variáveis úteis -->
  <PropertyGroup>
      <VersionNumber>1.0.0</VersionNumber>
      <BuildRoot>Deploy\Releases\$(VersionNumber)\</BuildRoot>
      <NewInstallDir>$(BuildRoot)Install\</NewInstallDir>
      <UpgradeDir>$(BuildRoot)Upgrade\</UpgradeDir>
      <CopyRoot>..\EruditoHAOC_PROD_test\</CopyRoot>
  </PropertyGroup>
  <ItemGroup>
      <SourceFiles Include="**\*.*" />
  </ItemGroup>
  <!-- Aqui entram as instruções para a compilação e cópia
      doas arquivos gerados para a pasta de deploy -->
  <Target Name="Build">
    <MSBuild
        Projects="MeuProjeto.sln"
        Properties="OutputPath=$(NewInstallDir)bin\" />
    <Copy
        SourceFiles="@(Content->'%(RelativeDir)%(FileName)%(Extension)')"
        DestinationFiles=
          "@(Content->'$(NewInstallDir)%(RelativeDir)%(FileName)%(Extension)')" />
    <Copy
        SourceFiles="@(None->'%(RelativeDir)%(FileName)%(Extension)')"
        DestinationFiles=
          "@(None->'$(NewInstallDir)%(RelativeDir)%(FileName)%(Extension)')" />
    <MakeDir
        Directories="@(Folder->'$(NewInstallDir)%(RelativeDir)')" />
    <CreateItem
        Include="$(NewInstallDir)**"
        Exclude="**\App_Themes\**;**\Web.config">
        <Output ItemName="UpgradeFiles" TaskParameter="Include" />
    </CreateItem>
    <Copy
        SourceFiles="@(UpgradeFiles)"
        DestinationFiles=
          "@(UpgradeFiles->'$(UpgradeDir)%(RecursiveDir)%(FileName)%(Extension)')" />
    <MakeDir Directories="@(Folder->'$(UpgradeDir)%(RelativeDir)')" />
  </Target>
  <!-- Um exemplo de como copiar todo o projeto para outro lugar -->
  <Target Name="Deploy">
    <Copy
      SourceFiles="@(SourceFiles)"
      DestinationFiles=
        "@(SourceFiles->'$(DeployRoot)%(RecursiveDir)%(FileName)%(Extension)')" />
  </Target>
</Project>

Para compilar seu projeto agora basta rodar o comando make msbuild.exe, da seguinte forma:

MSBuild.exe Makefile.proj /target:Build

Isto irá compilar e copiar o resultado da menira definida no xml Makefile.proj.

Referências:

Posted in programação, software, web | Tagged , , , | Leave a comment