sábado, 29 de janeiro de 2011

ASP.net MVC3: Usando HTML helper para incluir javascript files em Views

Em ASP.net MVC3 para quem não ainda conhece existe o HTML helper que um objeto para ajudar a construir objetos HTML com mais facilidade dentro dos Views do ASP.net MVC3.  Por exemplo:

@Html.TextBox("Nome")
Tenho certeza que todos já viram isso.


 Mas também você pode criar seus próprios Helper Methods anexados ao objeto HTML helper para incluir outros files ou arquivos.

 <script src='http://localhost:1633/Scripts/jquery-1.4.4.min.js' type='text/javascript'></script>
 <script src='http://localhost:1633/Scripts/jquery-ui-1.8.7.custom.min.js' type='text/javascript'></script>
 <script src='http://localhost:1633/Scripts/main.js' type='text/javascript'></script>


Vamos ver como se faz usando o HTML helper.


  1. Primeiro você precisa fazer é criar uma classe stática.
  2. Extraimos duas partes dos nosso link o urlSchema e urlAuth  que seria o Schema (http...) e o Authority (www.???.com....)
    urlSchema = HttpContext.Current.Request.Url.Scheme;
    urlAuth = HttpContext.Current.Request.Url.Authority;
  3. Criamos um method que tem como parameter o THML herlper com key work "This" que anexa o method ao HTML objeto para que você possa usar em qualquer view.
    public static string AddJQueryMinLink(this HtmlHelper helper)
  4. Por último a parte que retorna um string que contem o nosso HTML elemento.
     return string.Format("<script src='{0}://{1}/Scripts/jquery-1.4.4.min.js' type='text/javascript'></script>", urlSchema, urlAuth);

Código para adicionar ao View:

 @Html.Raw(Html.AddJQueryMinLink())
 @Html.Raw(Html.AddJQueryUICustomMinLink())
 @Html.Raw(Html.AddMainJS())


Abaixo você encontra o código completo.

Espero que ajude alguem.
Deylo

using System;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;


namespace SalonMVC3.Models
{
    public static class HTMLHelpers
    {
        private static string urlSchema;
        private static string urlAuth;
 
        static HTMLHelpers()
        {
            urlSchema = HttpContext.Current.Request.Url.Scheme;
            urlAuth = HttpContext.Current.Request.Url.Authority;
        }
 
 
        public static string AddJQueryMinLink(this HtmlHelper helper)
        {
            return string.Format("<script src='{0}://{1}/Scripts/jquery-1.4.4.min.js' type='text/javascript'></script>", urlSchema, urlAuth);
        }
 
        public static string AddJQueryUICustomMinLink(this HtmlHelper helper)
        {
            return string.Format("<script src='{0}://{1}/Scripts/jquery-ui-1.8.7.custom.min.js' type='text/javascript'></script>", urlSchema, urlAuth);
        }
 
        public static string AddMainJS(this HtmlHelper helper)
        {
            return string.Format("<script src='{0}://{1}/Scripts/main.js' type='text/javascript'></script>", urlSchema, urlAuth);
        }
 
    }
}

quinta-feira, 27 de janeiro de 2011

Mapear propriedades de um objeto para outro usando Reflection em C#

Muitas vezes você tem um groupo de objetos (POCO ou Models) que tem como função armazenar dados.  E muitas vezes você tem que mapear as propriedades de um objeto passando os valores de um para o outro.  Por exemplo, você tem um objeto chamado Cliente e você quer passar os valores para outro objeto Usuário que também possui as mesmas propriedades, você normalmente faria algo assim.


_cliente.Nome = _usuario.Nome;
_cliente.Endereco = _usuario.Endereco;

...

Se seu objeto tiver várias propriedades e se você precisar fazer isso em vários lugares fica sendo uma tarefa muito repetitiva.  E como programador nós aprendemos a refatorar o código para que tenha o mínimo possível de repetição.

Existe algumas soluções para esse problem, vou demonstrar como você usa Reflection in C# para fazer isso.

Considere os seguintes Methods.


 private static void AssignReflect(object fromObj, object toObj)
        {
            Type fromType = fromObj.GetType();
            Type toType = toObj.GetType();
            foreach (PropertyInfo fromInfo in fromType.GetProperties())
            {
                foreach (PropertyInfo toInfo in toType.GetProperties())
                {
                    //Assign values
                    if (fromInfo.Name.ToLower() == toInfo.Name.ToLower())
                    {
                        try
                        {
                            toInfo.SetValue(toObj, Convert.ChangeType(fromInfo.GetValue(fromObj, null),
                                            toInfo.PropertyType), null);
                            break;
                        }
                        catch (Exception e)
                        {
                            e.IsNull();
                            break;
                        }
                    }
 
                    //Clean Min SQL Datatime
                    CleanMinSQLDate(toObj, toInfo);
 
                    //Clean Null Strings
                    CleanNullStrings(toObj, toInfo);
                }
            }
        }
 
        private static void CleanMinSQLDate(object toObj, PropertyInfo toInfo)
        {
            if (toInfo.PropertyType == Type.GetType("System.DateTime"))
            {
                try
                {
                    DateTime dateValue = (DateTime)toInfo.GetValue(toObj, null);
                    if (dateValue.IsNull() || dateValue <= DateTime.MinValue)
                    {
                        toInfo.SetValue(toObj, Tools.GetMinSQLDate(), null);
                    }
                }
                catch (Exception ex)
                {
                    ex.IsNotNull();
                }
            }
        }
 
        private static void CleanNullStrings(object toObj, PropertyInfo toInfo)
        {
            if (toInfo.PropertyType == Type.GetType("System.String"))
            {
                try
                {
                    string stringValue = (string)toInfo.GetValue(toObj, null);
                    if (stringValue == null || stringValue == string.Empty)
                    {
                        toInfo.SetValue(toObj, string.Empty, null);
                    }
                }
                catch (Exception ex)
                {
                    ex.IsNotNull();
                }
            }
        }


O method AssignReflect recebe dois objetos como parameters, fonte e destino.
Em seguinte o tipo dos objetos e detectado.
Usando Reflection vamos fazer um loop nas propriedades dos dois objetos.
Comparamos os nomes das propriedades.
Se os nomes forem iguais, atribuir o valor de um objeto para outro, também usando Reflection.
Também esta incluido dois methods para ajudar, o CleanMinSqlDate para limpar as datas em formato SQL datetime, e method CleanNullStrings para limpar os strings nulls.

Para usar o method você teria que fazer o seguinte:


AssignReflect(_usuraio, _cliente);


Só isso mesmo.
Espero que ajude alguem.

Deylo Woo


p.s. outra opção é usar um API chamado AutoMapper
http://automapper.codeplex.com/wikipage?title=Getting%20Started&referringTitle=Documentation

terça-feira, 28 de dezembro de 2010

Fazer uma busca no Twitter com Javascript e JQuery

Ok galéra esse post vai ser bem curto só quero mostrar como você simplesmente e rápidamente pode fazer uma busca no twitter em um página de web, somente usando JQuery.


Linha 1: Instânciamos um variable Busca = Brasil, mas você pode tirar esse valor de uma caixa de texto ou qualquer outro componente.
Linha 2: Nessa linha usamos o Jquery para fazer um Chamada de HTTP tipo Get para o endereço no código em verde, passando dois parameters rpp=50 (número de tweets que retornará) e q=busca (o variable que contem a busca em string).  Vale apena notar que o retorno dos tweets será no formato JSON, simplificado e fácil de usar.
Linha 3: Essa e a função que usaremos para lidar com resposta com os dados. 
Linha 4: Checamos se os dados são null ou não.
Linha 10: Nessa linha é o loop por cada tweet retornado.
Linha 17: Baseado nas linhas 13-16, você pode implementar seu código para cada tweet

É só isso mesmo galéra, bem simples.
Até mais.
Deylo Woo

segunda-feira, 27 de dezembro de 2010

Como criar um Datagrid com ASP.net MVC 3

Nesse blog vou explicar como criar um Datagrid usando o ASP.net MVC.  Se você for um programador que tenha experiência com ASP.net Forms você deve estar acostumado com o componente Gridview que é usado para mostrar dados em formato de tabelas com colunas e cabeçalhos.  Algumas funções do Gridview é ajudar o usuário a visualizar todos os dados de uma forma gerenciável.  Imagine mostrar um resultado de endereços e clientes com mais 1000 recordes numa página só, não seria viável, nesse caso você usaria a função de paginar seu dados distribuindo o resultado em páginas, tabem clicando no cabeçalho existem as funçõe de classificar de acordo com a coluna, seja idade, estado, cidade ou qualquer outro campo.  O Datagrid e essas funções não existem no ASP.net MVC nativamente, você desenvolvedor terá que criar seu proprio mecanismo ou controle para gerar um Datagrid na sua página.

Então vamos ver como se faz, na verdade existem vários métodos e cada método vai de acordo com o desenvolvedor e o cenário em qual o método se enquadra.  Esse método que vou mostrar requere a manipulação dos dados na página com renderizção do Razor Engine que é novo com ASP.net MVC 3 RC2 e algumas manipulações do systema de Routing no arquivo global.asax do projeto.
Criar um projeto ASP.net MVC
Se você não tem o ASP.net MVC instalado, o processo mais simples de se instalar seria usando o WebPlatform Installer (WPI) que nada mais é do que um gerenciador de componentes, com o WPI você terá a opção de instalar Visual Web Developer 2010 Express e todos os outros componentes para criar um aplicativo em ASP.net MVC.
Você pode baixar o WebPlatform Installer aqui nesse site da Microsoft.
http://www.microsoft.com/web/downloads/platform.aspx

Depois que você instalar tudos requesitos, abra o Visual Web Developer 2010 Express (VWD).  No VWD você selecione New Project.  Então você tera a opção de criar vários tipos de projetos e se você instalou tudos os requisitos ASP.net MVC 3 Web Application será uma das opções.


Você percebe que existe dois tipos de ASP.net MVC versão 2 e 3.  Nesse projeto usaremos a versão 3 que usa o Razor Engine para renderização das páginas.  Selecione ASP.net MVC 3 Web Application e modifique o nome do projeto para Loja_Do_Chico e clique OK. 

Consequentemente o VWD pede para selecionar qual o View Engine que será usado no projeto, selecion Razor e clique OK.



No nosso projeto coloquei o nome de "Loja do Chico".  Para que possamos ilustrar a função do Datagrid precisamos de um Data Source ou seja uma fonte de dados, onde possamos fazer uma consulta ao banco de dados para adiquirir os dados. 

Adicione um banco de dados SQL Express
O próximo passo e adicionar um banco de dados ao nosso projecto mais precisamente adicionar um archivo de SQL Express e configura-lo como nosso banco de dados.  No VWD navegue até o Solution Explorer onde mostra a lista de todos os seus archivos e pastas.  La você encontrará uma pasta chamada App_Data, essa pasta é usada para armazenar arquivos de banco de dados.  Clique com o botão direito nessa pasta App_Data e selecione Add depoin New Item.  Agora selecione SQL Server Database e nomei o archivo de banco de dados como LojaDoChico.mdf depois clique Add para finalizar.




Agora precisamos abrir o banco de dados que acabamos de criar no Database Explorer para criarmos uma tabela e adicionar dados.  Selecione Database Explorer do menu.  No menu selecione View/Other Windows/Database Explorer.  No Databae Explorer você vai selecionar Connect to Database e o dialog para adicionar a conecção aparece.  Você selecione SQL Server Database File e selecione o archivo que criamos para o projeto na pasta App_Data.



Com o banco de dados o primeiro passo é adicionar uma tabela (Faturas) para ilustrar esse exemplo.  Clique com botão direito na pasta de Tabelas (Tables), selecione Add New Table para adicionar uma nova tabela.  Nessa tabela vamos adicionar os seguintes campos FaturaId = o Primary Key que vai identificar cada fatura de uma forma única, DataDeEnvio = data em que a fatura foi criada, NomeDoCliente = nome do cliente (Na prática eu colocaría em dois campos ou outra tabela), ValorTotal = valor total da fatura, se tivéssimos uma outra tabela com cada item da fatura esse seria a soma do valor de todos os items para essa fatura, Pago = boolean indicando caso foi pago ou não, Cidade e Estado = cidade estado do cliente.  Uma tabela bem simples sem complexidade de relações com outras tabelas.




Vale a pena observar que o FaturaId tem o Data Type de UniqueIdentifirer tambem conhecido no C# como GUID, esse id e gerado para ser na teoria irrepitível.  O FaturaId id está configurado como Primary Key e Identity = yes no banco de dados.  A configuração Identity = yes adiciona um GUID auto gerado se o campo FaturaId estiver em branco quando o recorde for adicionado.  Tambem observem o Data Type dos outros campos.

Agora precisamos adicionar dados nas tabelas para que possamos construir e testar nosso Datagrid.
Clique com botão direito na tabela (Faturas) e selecione Show Table Data.  Agora você adicionará alguns recordes para que possamos testar.




Criar um Data Context
Próximo passo é adicionar um archivo (*.edmx), tabem conhecido com Database Context que faz parte do Entity Framework.  Esse archivo ou componente e responsável por mapear todos os objetos Modelos (POCO) baseado nas tabelas do seu banco de dados.  Em outras palavaras o arquivo vai criar uma classe para cada tabela do banco de dados e converter todos os campos para propriedade da classe, tambem criara todos as funções necessárias para adicionara, remover, update e deletar no banco de dados.  Esse componente tambem pode ser costumizado para criar classes que refletem campos de duas ou mais tabelas, classes mais complexas.  Mas para simplicidade vamos so mapear uma tabela para uma classe, Faturas.

Na pasta Models clique com botão direito e selecione Add/Class e selecione ADO.Net Data Model e coloque o nome de LojaDoChico.edmx


Clique Add para adicionar.

No próximo dialog do Entity Data Wizard, perguntará o que o Modelo deve conter?
Selecione Generate from Database para geral os Modelos baseado no banco de dados.

Qual conecção ao banco de dados deve usar, selecion LojaDoChico.mdf, selecion Save entity connection settings in Web.config as para salvar no web.confing o connection string, e clique Next. Agora selecione somente a tabela Faturas para o Modelo ser gerado e clique Finish para concluir.

Depois de concluido, na pasta Models terá um archivo LojaDoChico.edmx e um LojaDoChico.Designer.cs, esse último archivo contem o codigo gerado que reflete a tabela (Faturas) juntamente com as funções necessárias para manipulação dela.

Construir o Model, o View e  o Controller
Agora temos quase tudo alinhado na parte de banco de dados para que possamos fazer nosso Datagrid, o que devemos construir agora é um metodo que retornará um View para mostrar o Datagrid.  No nosso caso vamos construir um Controller, Metodo, e o View e Model para que possamos usar no View.

Na pasta Models clique com botão direito e selecione Add/Class coloque o nome de FaturaDatagrid.cs.  Essa classe vai conter uma lista de faturas IList<Faturas> sendo a classe Fatura a classe criada pelo Database Contexct (*.edmx) que mapeamos ao banco de dados, e as propriedades para regular as funções do Datagrid paginas e classificar em ordem por colunas.



Essa classe que criamos vamos tambem usar para produzir o nosso View.

O próximo passo é adicionar o Controller.  Na pasta Controllers clique com botão direito e selecion Add/Controller coloque o nome de FaturaController, não selecione Add action methods for create, update, delete... caso selecionado criarar-se metodos para fatura, no nosso caso vamos criar manualmente.  Clique Add para adicionar o controller.




Observe que o FaturaController foi adicionado à pasta Controllers e ao abrir esse archivo você encontrará somente um  metodo Index().  Vamos usar esse metodo mesmo para mostrar nosso View. 

Tambem vou adicionar uma outra classe que ajuda com Linq query para criar queries dinâmicas contra o banco de dados.  Essa classe se chama Dynamic e você pode baixar aqui  http://msdn2.microsoft.com/en-us/vcsharp/bb894665.aspx , e bem simples de usar, é so você adicionar a classe á pasta Models depois no FaturaController adicionar uma referência ao name space System.Linq.Dynamic.  Uma das vantagens de software e reusabilidade de componetes, o Dynamic um exemplo de use componentes criados por outros que ajudam o desenvolvimento, "não existe necessidade de reinventar a roda". (Dynamic foi criado pela Microsoft porem não é standard com projetos)



De volta á classe FaturaController.cs vamos implementar o método Index(), vamos adicionar um intãncia ao DatabaseContext (LojaDoChico.edmx) para que possamos fazer queries contra o banco de dados.  Também vamos adicionar parameters ao metodo Index(), esse parameter serão as propriedades requesitas para que possamos fazer nosso query e formar nosso Datagrid.  No metodo Index() também criamos um instância do FaturaDatagrid na pasta Models, essa instância será retornada do metodo para que possamos contruir o View.



Vamos analizar o método Index().


Os variables passados pelo parameter do Metodo são:
  • campo: O campo o qual o Datagrid vai ser classificado
  • derecaoDeOrder: Qual a direcão da ordem, crescendo ou subindo
  • pagina: O numero da página requesitado
  • itenPorPagina: Quantidade de itens por página
  • mudarOrder: se deve mudar a order antes de fazer o Query
Esse são os variables que controlam o Datagrid, vale notar que com C# 4.0 você tem a opção de passar parameter opcionais adicionando o valor Default. 
Linha 26 e 27 decide se deve mudar de orden, linhas 29-35 somente configuramos o faturaDatagrid com os variables requesitos para construir o grid, linhas 36-40 e nosso query contra o banco de dados e o resultado das faturas convertido para um Lista e referenciado a faturaDatagrid.Faturas, note que a parte OrderBy(campo + " " + direcaoDeOrden) usa o Linq.Dynamic a classe que criamos, isso ajuda facilitar a criação do Dynamic query.  O por último linha 42 que retorna o faturaDatagrid como as definições do DataGrid e o resultado das faturas.

Próximo passo é adicionar o View. Na classe FaturaController memos clique com botão direito no metodo Index() e selecion Add/View para adicionar o View para esse metodo Index.  Deixe o nome do View como Index, selecione o Razor como view engine, selecione Create Strongly Typed View e selecione  Fatura do Model Name Space, selecione List no Scaffold template, não selecione Create as Partial View, selecione Use a Layout or master page navegue até o View _layout.cshtml.  Depois clique Add. Como na ilustração abaixo.


Depois de adicionar, uma pasta Fatura foi criada dentro da pasta Views, dentro desta pasta foi criado o view Index.cshtml. Esse view foi criado baseado na class Fatura que selecionamos no Scafold Template List.  Você pode observar que syntax do Razor e um pouco diferente, mais simplificado e mais facíl de escrever.  Se você quizer aprender mais sobro o Razor clique aqui http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx


Agorava vamos modififcar esse view para ficar igual a ilustração abaixo, vamos analizar cada bloco de código desse View.
continuação

  • Linha 1, invez de usar a classe modelo Fatura vamos usar o FaturaDatagrid, a razão que usamos a classe Fatura inicialmete e queremos que o VWD construa o código inicial para mostrar a list de Faturas.
  • Linha Abaixo da linha 10 vamos inserir un <div> com os settings selecionados para o Datagrid
  • Dentro da nossa tabela <Table> dentro do primeiro <TR> você vai encontrar o cabeçalho do nosso Datagrid, vamos modificalo para refletir as funções the classificação como mostra na ilustração abaixo. Vamos usar o link para passar os parameter para o FaturaController no metodo Index.  O link renderizado ficaria assin: http://localhost:2664/Fatura/Index/DataDeEnvio/desc/1/5/False sendo Fatura o nome do Controller, Index o nome da ação nosso caso metodo index, o campo de classificação nesse caso DataDeEnvio, a direção de classificação nesse caso desc, pagina 1, e 5 itens por página, e por último mudar ordern False. Esse e o código usado para renderizar o link.
    <a href="@string.Format("{0}://{1}", Request.Url.Scheme, Request.Url.Authority)/Fatura/Index/DataDeEnvio/@Model.DirecaoDeOrden/@Model.Pagina/@Model.ItensPorPagina/True">Data de Envio</a>
  • O próximo pásso é modificar o foreach() loop que vai criar as faturas no Datagrid, em vez de usarmos o Model vamos usar o Model.Faturas que usa a classe faturaDatagrid que mudamos na Linha 1.  Também costumizar para cada tipe da dados, como $ e datas.
  •  Por último adicionamos um foreach() loop depois da tabela </table>, esse procedimento vai gerar os números de página usadas no datagrid de acordo com o resultado. Vale notar que as os números de páginas não mudam a orden de classificação por is isso é False no final do link.
No view é so isso mesmo, porem nosso trabalho não está completo.

Configuração do Routing dos URLs
Agora para o úlitmo passo adicionar um configuração no systema de routing para que possamos mapear o nosso URL http://localhost:2664/Fatura/Index/DataDeEnvio/desc/1/5/False de acordo com on método Index na classe FaturaController.  Abra o archivo Global.asax.cs no seu projeto e dentro do metodo RegisterRoutes() adicione o seguinte código.

routes.MapRoute("","Fatura/Index/{campo}/{direcaoDeOrden}/{pagina}/{itemsPorPagina}/{mudarOrder}",new { controller = "Fatura", action = "Index" });

Como você pode observer esse código ilustra a estrutura do nossso URL que criamos para controlar nosso Datagrid.  Abaixo está a ilustração do Global.asax.cs.


Agora é so correr o programa, abrir o seguinte URL http://localhost:2664/Fatura/Index e você verá o seguinte view com o Datagrid.



Esse é o nosso Datagrid você pode clicar nas colunas para classificar e clicar nos números abaixo para mudar de págnias.  Você também pode manipular simplesmente mudando os valores no URL que seria muito interessante para programas que scaneam a Web.  O URL não o único método de passar informação para o Controller, você também pode user o ViewData[""] que funciona como um dicionário e outros metodos também.

Você tambem pode adicionar outras colunas que possam criar links para deletar, editar ou abrir detalhes mapeando no sistema de Routing do ASP.net MVC aos metodos no Controller.

Conclusão
Nesse Post nós vimos como é fácil construir seu Datagrid com ASP.net MVC criando um projeto novo, criamos o Database Context (archivo *.edmx) para fazer queries contra nosso banco de dados. 
Tambem vimos como adicionar um Controller, Model, e View.  Configuramos o metodo Index do FaturaController para retornar o resultado correto.  Criamos e adicionamos os parameters necessários para manipular o Datagrid no faturaDatagrid na pasta modelo.  Configuramos o view que usa o Razor Engine na construção do HTML do Datagrid, e por último configuramos Routing no Global.asax.cs para mapear com o metodo Index na classe FaturaController.

Você pode baixar o projeto complete aqui. http://www.deylowoo.com/Loja_do_Chico_done.rar

Espero que esse Post venha ajudar alguem. 
Boa sorte!
Deylo Woo