Integrando Google Maps com Foursquare

Jan 05
2012

Recentemente adicionei um projeto ao Github que, na minha opinião, vale a pena ser compartilhado aqui no blog.

A minha intenção era adicionar um mapa na página web e quando o usuário clicasse no mapa a aplicação efetuaria a leitura do Foursquare buscando lugares cadastrados.

Veja a página inicial abaixo:

 

Assim, após o usuário clicar em algum lugar do mapa é exibido algumas opções de lugares. Veja abaixo:

 

 

O que á mais legal é que para qualquer lugar DO MUNDO é exibido opções de lugares…o que inicialmente eu não havia previsto.

Se quiser pegar o código: https://github.com/RobsonRamos/IntegrationGoggleMapsAndFoursquare

Até +!

Github

Jan 05
2012

Github

Ola pessoal, tudo bem?

 

Gostaria de compartilhar o link para  a minha conta no Github: https://github.com/RobsonRamos

 

Não sabe o que é Github?

 

Github é um rede social para desenvolvedores, onde nós podemos compartilhar nossos projetos com os outros.

Só tenho uma coisa a dizer: O Github é fantástico

Tenho poucos projetos por enquanto, mas, quando tiver mais tempo vou subir alguns que estão parados já faz um tempo.

 

Até +!

HTML 5 – Novos componentes

Jan 03
2012

Neste artigo vamos analisar alguns dos vários componentes introduzidos pelo HTML 5. Posso afirmar que há grandes novidades para a criação dos nossos formulários. Agora temos novos componentes, atributos,várias mudanças semânticas e também adição de dois tipos de form actions (update e delete).

Obs: para a grande maioria dos exemplos abaixoutilizei a última versão do navegador Opera.

 

Componentes fora do formulário

 

Anteriormente, nossos componentes tinham que estar obrigatoriamente contidos dentro das tags do nosso  formulário para que pudessem ser submetidos para o servidor.

Agora, isto não é mais necessário!

Podemos ter nossos componentes em qualquer lugar da página apenas informando a qual formulário ele pertence. Observe o trecho abaixo:


<form id=myForm>

<input type=text>

...

</form>

<textarea form=myForm></textarea>

Podemos observar que a área de texto (textarea) não está dentro da nossa tag form, ela está fora dela e através do atributo form indicamos a qual formulário o componente pertence.

 

Novos componentes

 

Com a nova versão do HTML novos componentes foram introduzidos, tornando ainda mais prazeroso trabalhar com a linguagem.

Chega de ter que recorrer à biblioteca de terceiros (JQuery UI e outras) para ter que usar um calendário ou uma slide bar.

Agora temos a possibilidade de usar os próprios recursos nativos sem ter que necessitar de biblioteca de terceiros para suprir a falta de componentes.

Vale lembrar que a especificação não define como cada navegador ou dispositivo apresentará cada componente. Portanto, podemos ter diferentes aparências para um mesmo componente dependendo do fabricante ou dispositivo.

 

Email

 

<body>
   <input type=email>
</body>

Viram como é fácil a sua utilização?

A tag acima diz ao browser não submeter o formulário se o usuário não entrar com um formato válido de e-mail (claro que não é checado se o e-mail existe!). Mas, a especificação não define como será exibida a mensagem de erro para o usuário.

Além disso,  é importante consultar as regras de validação no site da W3C.

Caso as regras de validação não atendam a sua necessidade, fique tranquilo! É possível customizá-la, o que faremos em artigos mais adiante.

Podemos visualizar como o Chrome e o Opera se comportam quando entramos com um e-mail com formato incorreto:

Email - Chrome

Email - Opera

Data, hora, mês e semana

 


<body>
 <input type=datetime>
 <input type=date>
 <input type=time>
 <input type=month>
 <input type=week>
</body>

As tags acima são auto-explicativas e tornam a tarefa de trabalhar com datas/horas muito mais fácil, sem necessitar de bibliotecas de terceiros.

Obseve abaixo o efeito no navegador Opera:

Datetime - Opera

 

 

 

 

 

 

 

 

 

 

 

 

 

Podemos ver que o navegador forneceu nativamente um calendário, facilitando bastante o nosso trabalho.

 

Number


<body>
 <input type=number>
</body>

 

Permite somente a entrada de valores numéricos. Veja abaixo o efeito gerado por esta tag:

Number - Opera

Range

<body>
 <input type=range>
 </body>
 

 

O componente range é um dos meus favoritos e permite que o usuário selecione através de um slider valores dentro de aguns limites possíveis. Observe o efeito nos nossos amigos Chrome e Opera:

Range - ChromeRange - Opera

Posteriormente, faremos um exemplo mais elaborado utilizando os novos atribuos max, min e step =)

 

Search

<body>
 <input type=search>
</body>

 

Especifica um campo de busca. Com a ajuda do navegador, pode ser fornecido ao usuário um histórico das páginas visitadas recentemente. A diferença entre este campo e um campo de texto é apenas semântica.

Search - Chrome

 

 

 

Tel

<body>
 <input type=tel>
</body>

 

 

Esta tag espera um telephone como entrada, porém, não há nenhuma validação especial definida pela especificação. Mas, com o HTML5 podemos adicionar aos nossos componentes regras de validação.

Assim como a tag search, a diferença é apenas semântica. Alguns dispositivos podem facilitar a vida do usuário apenas exibindo o teclado numérico quando o foco estiver neste campo.

Tel - Opera

 

 

 

Color


<body>

<input type=color>

</body>

 

Permite que os usuários entrem com uma cor válida. Podemos ver abaixo que o Opera exibe uma paleta de cores com algumas opções:

Color - Opera

 

 

 

 

 

Para concluir, vale lembrar que muitos navegadores não possuem suporte à estas tags e que muita coisa ainda está por vir, mas, vimos o quanto o HTML 5 facilitará a nossa vida =) No próximo artigo irei abordar alguns novos atributos para que possamos fazer alguns exemplos mais elaborados. Até a próxima!

 

Consulte a série de artigos sobre HTML5: http://robsonramos.com/index.php/category/html-5/

HTML5 – Introdução

Dec 31
2011

HTML 5

 

Recentemente decidi focar meus estudos em HTML 5 e tentar entender o que mudou e o motivo pelo qual esta tecnologia esta gerando tanto “barulho”.

 

História

 

A última versão até então era o XHTML 1.0, que tentava aproximar o HTML com XML. Foram desenvolvidas duas versões:

  • Transitional: Não tão rigorosa, tinha a finalidade de ajudar as pessoas a moverem seus sites para esta nova especificação.
  • Strict: Mais rigorosa, pois, na sua validação mais regras eram aplicadas.

 

Após isso, os trabalhos se reiniciaram visando a versão 2.0 do XHTML, porém, esta nova especificação propunha mais alterações na linguagem, o que quebraria a compatibilidade com as versões anteriores. Então, um pequeno grupo, que trabalha(va) para empresa Opera, e que não estava contente com a união com o XML começou a trabalhar em uma nova especificação do HTML sem quebrar a compatibilidade das versões anteriores. Com isso, o grupo aumentou de tamanho, ganhando a adesão de membros da Mozilla (liderados por Ian Hickson). Assim, este grupo se auto-intitulou WHATWG (Web Hypertext Application Technology Working Group, www.whatwg.org).

Em 2006, a W3C reconheceu que talvez tenha sido otimista demais em esperar que todos mudassem para algo similar ao XML e quebrar a compatibilidade existente. Então, foi decidido usar a especificação que estava sendo desenvolvida pelo WHATWG como a nova especificação do HTML.

Assim, o processo de definição da nova especificação foi aberto, qualquer um poderia contribuir e dar sugestões bastando enviar e-mails ou participar da lista de discussão do WHATWG.

 

A especificação e novas idéias têm sido desenvolvidas com uma velocidade muito grande e, portanto, o HTML 5 tem grande chance de se tornar um padrão de fato. Um número muito grande de empresas têm apoiado o projeto e os fabricantes de browsers (inclusive o IE da Microsoft) se comprometeram a implementar as especificações numa colaboração nunca antes vista.

 

Estrutura básica

 

Analise o trecho abaixo:

 


<!doctype html>

<html lang=en>

<head>

<meta charset=utf-8>

<title>HTML 5</title>

</head>

<body>

<p>Um parágrafo qualquer...</p>

</body>

</html>

 

A primeira coisa que podemos notar é que o doctype é muito simples, nada de urls nem número de versão.

Na tag html não é mais necessário usar as aspas (repare a definição da lang). Mas, quando houver espaço nos valores, será necessário utilizá-las.

 

Na quarta linha é definida a tag meta e o encoding da página (lembre-se como era definida esta tag antes: <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8”>.). Pelo que eu tenho lido, não definir o enconding tem gerado um erro estranho em alguns navegadores.

 

Obs: Apesar das tags html e body serem opcionais, decidi incluí-las neste exemplo.

 

Novos elementos

 

Em 2004, Ian Hickson utilizou o Google Index analisou uma lista de sites e observou como eles estavam estruturados. Basicamente, haviam as mesmas classes de elementos nos sites (por exemplo: footer, menu, text, content, title, main, clear, search, nav, logo). Com base nisso, você perceberá que muitos elementos foram criados com estes nomes, com a finalidade de obter uma melhor semântica nas nossas páginas.

 

Sendo assim, ao invés de criarmos div’s genéricas da seguinte forma:

<div class=”header”>

<div class=”nav”>

<div class=”content”>

<div class=”footer” >

 

Passaremos a usar elementos que definirão de uma forma mais inteligente o que conteúdo das nossas páginas, por exemplo:

 

<header></header>

<nav></nav>

<footer></ footer >

 

 

 

Bom, esta é uma introdução MUITO básica sobre o que é o HTML 5.

Por hoje é só, mas, vou continuar postando sobre este assunto em breve!

EF Code First – Criando chaves que não sejam Identity

Dec 22
2011

Na construção de nossas aplicações há alguns casos em que queremos que uma coluna seja chave primária de uma determinada tabela, mas, queremos que esta informação não seja gerada pelo banco de dados, ou seja, queremos que esta informação seja fornecida pelo usuário ou seja obtida de outra forma (através de um cálculo ou através de uma consulta a um sistema externo).

Para exemplificar, vamos então analisar a classe abaixo:

public class Pessoa
{
    public int CPF { get; set; }
    public string Nome { get; set; }
    public string Sobrenome { get; set; }
    public int Idade { get; set; }
}

 
Como você pode ver esta classe é bem simples, ela contêm algumas informações de cadastro de uma pessoa. A nossa intenção principal aqui é que a informação de CPF seja fornecida pelo usuário que esteja efetuando o cadastro.
 
Vamos criar então outra classe chamada PessoaConfiguration, conforme abaixo:

class PessoaConfiguration : EntityTypeConfiguration<Pessoa>
{
    public PessoaConfiguration()
    {
        HasKey(p => p.CPF);
        Property(p => p.Nome).IsRequired();
        Property(p => p.Sobrenome).IsRequired();
    }
}

 
Obs: Se você quiser aprender mais sobre o código acima, sugiro a leitura do artigo:
Data Annotations x Fluent Api
 

Esta classe faz uso da Fluent API para configurar a classe Pessoa. Sendo assim, configuramos a propriedade CPF como chave primária da tabela e informamos que a propriedade Nome e Sobrenome serão obrigatórias.
 

Mas, o que há de errado com o código acima?

 
Vamos então tentar criar um registro no banco de dados. Veja o código abaixo:

static void Main(string[] args)
{
       var pessoa = new Pessoa
       {
           Nome = "Robson",
           Sobrenome = "Ramos"
       };

       using (var context = new Context())
       {
          context.Pessoas.Add(pessoa);
          context.SaveChanges();
       }
}

 
O código acima efetua a criação de um objeto Pessoa e efetua a inserção no banco de dados. Observe que não forneci a informação de CPF (que estava configurada como obrigatória). Veja como o registro foi criado na tabela:
 

 
Apesar da propriedade CPF ser configurada como obrigatória, o banco de dados gerou um id para ela. Isto aconteceu devido ao modo de funcionamento do Entity Framework: ao encontrar um campo inteiro configurado como chave primária ele então configurará a chave primária como Identity (auto-incrementável) no banco de dados.

Para resolvermos este problema, basta efetuar a seguinte configuração na classe PessoaConfiguration. Conforme abaixo:

 

class PessoaConfiguration : EntityTypeConfiguration<Pessoa>
{
    public PessoaConfiguration()
    {
        HasKey(p => p.CPF);
        Property(p => p.CPF).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        Property(p => p.Nome).IsRequired();
        Property(p => p.Sobrenome).IsRequired();
    }
}

 
Observe sexta linha do código acima, esta instrução diz que a coluna CPF não terá seu valor gerado pelo banco de dados, ou seja, estamos sobrescrevendo a convenção do Entity Framework para que o valor seja informado no momento da inserção do registro.

Agora, precisamos alterar o código que instancia o objeto pessoa informando um número de CPF. Veja abaixo:

static void Main(string[] args)
{
            var pessoa = new Pessoa
            {
                CPF = 12345678,
                Nome = "Robson",
                Sobrenome = "Ramos"
            };

            using (var context = new Context())
            {
                context.Pessoas.Add(pessoa);
                context.SaveChanges();
            }
}

 
Agora, se olharmos na tabela podemos verificar que a informação agora foi salva com sucesso:
 

EF Code First – Data Annotations x Fluent API

Dec 22
2011

Ao se trabalhar com o Entity Framework usando o modo Code First há a possibilidade de se trabalhar de duas formas com as configurações do nosso Model : Data Annotations e Fluent API. Neste artigo mostarei como cada configuração sem comporta e tentarei estabelecer os prós e contras de cada uma.

Para iniciarmos crie um projeto do tipo Console Application (dê o nome que você acha mais conveniente) e usando o Nuget procure o pacote do Entity Framework e clique em Install. Conforme abaixo:

NuGet

Após isso, crie uma classe chamada Carro e adicione algumas propriedades igual ao código abaixo:

class Carro
{
    public int CarroId             { get; set; }
    public string Fabricante       { get; set; }
    public string Modelo           { get; set; }
    public string Placa            { get; set; }
}

Data Annotations

Data Annotations são atributos que aplicamos diretamente ao nosso Model com a finalidade de efetuarmos validações, definir formatos de campos, ajudar o Entity Framework no processo de geração do banco de dados, dentre outras coisas…

Vamos então alterar a nossa classe criada anteriormente.


[Table("Automoveis")]
class Carro
{
[Key]
public int CarroId { get; set; }

[Required]
public string Fabricante { get; set; }

[Required]
public string Modelo { get; set; }

[MaxLength(8)]
public string Placa { get; set; }
}

Obs: Para o código acima é necessário referenciar o assembly System.ComponentModel.DataAnnotations

O código acima efetuou as seguintes configurações:

• Esta classe será mapeada para a tabela Automóveis
• A propriedade CarroId é chave primária
• A propriedade Fabricante é obrigatória
• A propriedade Modelo também é obrigatória
• A propriedade Placa deve ter no máximo dígitos

Fluent API

O conceito de Fluent API não vêm do Code First, mas, a sua idéia principal é usar chamada de métodos para produzir código fácil de ler e entender aos olhos do desenvolvedor. Com a ajuda do IntelliSense e fazendo uso de expressões lambda podemos configurar as nossas classes usando uma classe separada só para cuidar disso.

Antes de fazermos as alterações, remova os atributos adicionados no passo anterior. Embora seja possível trabalhar das duas maneiras é recomendável usar apenas umas das duas formas.

Depois disso, crie mais uma classe chamada CarroConfiguration e adicione o código abaixo:

class CarroConfiguration : EntityTypeConfiguration<Carro>
{
    public CarroConfiguration()
    {
        ToTable("Automoveis");
        HasKey(c => c.CarroId);
        Property(c => c.Fabricante).IsRequired();
        Property(c => c.Modelo).IsRequired();
        Property(c => c.Placa).HasMaxLength(8);
    }
}

Pronto, é só isso!

As configurações acima tratam-se das mesmas configurações realizadas utilizando o Data Annotation.

Mas, para que o Entity Framework possa reconhecer a nossa classe como “configuradora” da classe Carro precisamos registrá-la no processo de criação do Model, mas, isso é assunto para outro post. =)

Conclusão

Embora os dois métodos são bem simples eu, particularmente, gosto bastante de trabalhar com a Fluent API. Isto porque a adição de inúmeros atributos no nosso Model poluirá visualmente a nossa classe e tornará a leitura complicada. Além disso, com a Fluent API temos uma separação clara de responsabilidade entre o Model em si a sua configuração.
Um outro ponto a se levar em consideração é que há algumas configurações que só podem ser alcançadas com a Fluent API, pois, o uso de atributos possui algumas limitações a serem levadas em consideração.

Tabela de Helper Methods mais comuns

Sep 23
2011
Helper Method Exemplo Output
Html.BeginForm @using (Html.BeginForm(“Index”, “Home”)) <form action=”/Home/Index” method=”post”></form>
Html.CheckBox Html.CheckBox(“myCheckbox”, false) <input checked=”checked” id=”myCheckBox” name=”myCheckBox” type=”checkbox” value=”true” />
Html.Hidden Html.Hidden(“myHidden”, “val”) <input id=”myHidden” name=”myHidden” type=”hidden” value=”val” />
Html.RadioButton Html.RadioButton(“myRadiobutton”, “val”, true) <input checked=”checked” id=”myRadiobutton” name=”myRadiobutton” type=”radio”
value=”val” />
Html.Password Html.Password(“myPassword”, “val”) <input id=”myPassword” name=”myPassword” type=”password” value=”val” />
Html.TextArea Html.TextArea(“myTextarea”, “val”, 5, 20, null) <textarea cols=”20″ id=”myTextarea” name=”myTextarea” rows=”5″>val</textarea>
Html.TextBox Html.TextBox(“myTextbox”, “val”) <input id=”myTextbox” name=”myTextbox” type=”text” value=”val” />
Html.CheckBoxFor Html.CheckBoxFor(x => x.IsApproved) <input id=”IsApproved” name=”IsApproved” type=”checkbox” value=”true” />
Html.HiddenFor Html.HiddenFor(x => x.SomeProperty) <input id=”SomeProperty” name=”SomeProperty” type=”hidden” value=”value” />
Html.RadioButtonFor Html.RadioButtonFor(x => x.IsApproved, “val”) <input id=”IsApproved” name=”IsApproved” type=”radio” value=”val” />
Html.PasswordFor Html.PasswordFor(x => x.Password) <input id=”Password” name=”Password” type=”password” />
Html.TextAreaFor Html.TextAreaFor(x => x.Bio, 5, 20, new{}) <textarea cols=”20″ id=”Bio” name=”Bio” rows=”5″>Bio value</textarea>
Html.TextBoxFor Html.TextBoxFor(x => x.Name) <input id=”Name” name=”Name” type=”text” value=”Name value” />
Html.DropDownList Html.DropDownList(“myList”, new SelectList(new [] {“A”, “B”}), “Choose”) <select id=”myList” name=”myList”>
<option value=”">Choose</option>
<option>A</option>
<option>B</option>
</select>
Html.DropDownListFor Html.DropDownListFor(x => x.Gender, new SelectList(new [] {“M”, “F”})) <select id=”Gender” name=”Gender”>
<option>M</option>
<option>F</option>
</select>
Html.ListBox Html.ListBox(“myList”, new MultiSelectList(new [] {“A”, “B”})) <select id=”myList” multiple=”multiple” name=”myList”>
<option>A</option>
<option>B</option>
</select>
Html.ListBoxFor Html.ListBoxFor(x => x.Vals, new MultiSelectList(new [] {“A”, “B”})) <select id=”Vals” multiple=”multiple” name=”Vals”>
<option>A</option>
<option>B</option>
</select>
Url.Content Url.Content(“~/my/content.pdf”) /my/content.pdf
Html.ActionLink Html.ActionLink(“Hi”, “About”, “Home”) <a href=”/Home/About”>Hi</a>
Url.Action Url.Action(“About”, “Home”) /Home/About
Html.RouteLink
Html.RouteLink(“Hi”, new { controller = “c”, action = “a” }, null) <a href=”/c/a”>Hi</a>
Html.RouteLink(“Hi”, “myNamedRoute”, new {}) <a href=”/url/for/named/route”>Hi</a>

Entendendo como o Razor renderiza Views

Sep 21
2011

Neste artigo vamos tentar entender como o Razor efetua o processo de renderização das nossas Views à partir de uma request. Além disso, vamos ver como o nosso código C# escrito nas nossas views acaba sendo gerado por trás dos panos. Let’s Go!

Só para contextualizarmos, o  Razor interpreta as nossas views somente quando o nosso aplicativo é executado. A grande sacada por trás disso é que as nossas views são traduzidas para classes C#. Isso mesmo, escrevemos o nosso HTML e C# na View para no final ser gerada uma classe. Se pararmos para pensar, este é o motivo pelo qual podemos incluir trechos de código C# dentro das nossas views, pois, estes trechos de código acabarão sendo inseridos dentro de uma classe a ser gerada. Mais adiante veremos o que acontece com o HTML inserido na view também.

Vamos começar criando um projeto do tipo MVC3 com o template do tipo Empty. Após isso, adicione um Controller com o nome HomeController (ou qualquer outro nome à sua escolha) e em seguida adicione o trecho de código abaixo:


public ActionResult Index()
{
     List<string> nomes = new List<string>{"Robson", "João", "maria"};

     return View(nomes);
}

O código acima não tem nada de especial, simplesmente cria uma coleção de strings com alguns nomes e passa esta coleção para a View. Após isso, vamos criar a nossa View selecionando a opção de view fortemente tipada e informando como model class uma List<string>, pois, estamos enviando para a nossa view uma coleção de strings. Veja abaixo:

Com a view criada, adicione o código abaixo:


@model List<string>

@{ ViewBag.Title = "Cadastro de Nomes"; }

<h2>Nomes Informados</h2>

<ul>

    @foreach (var nome in Model)
    {

        <li>@nome</li>

    }
</ul>

O código acima apenas recebe a lista de nomes e as exibe dentro de uma lista ul.

Agora vamos começar a analisar o que acontece durante este processo. Como dito anteriormente, todas as views são traduzidas para classes C# quando o nosso aplicativo é executado. Vamos então executar a nossa aplicação para que a nossa view seja traduzida para a sua respectiva classe. As classes geradas serão salvas no diretório (caso esteja usando o Windows 7):

C:\Users\<Usuário>\AppData\Local\Temp\Temporary ASP.NET Files\root

Dentro desta pasta, temos que localizar o arquivo gerado. Mas, para localizá-lo devemos “fuçar” no conteúdo das pastas deste diretório, pois, o nome do arquivo não é nada intuitivo. Se for conveniente você pode parar a execução da aplicação, apagar todas as pastas dentro deste diretório e executar novamente a aplicação. Assim, será gerada apenas a pasta na qual contêm os códigos da nossa aplicação.

Depois de muito procurar, consegui localizar o arquivo gerado pelo Razor. O nome dele era  App_Web_xjjfolqg.1.cs (o seu arquivo pode conter um nome diferente!). Vamos então analisar o conteúdo deste arquivo:

namespace ASP
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Web;
    using System.Web.Helpers;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.WebPages;
    using System.Web.Mvc;
    using System.Web.Mvc.Ajax;
    using System.Web.Mvc.Html;
    using System.Web.Routing;

    public class _Page_Views_Home_Index_cshtml : System.Web.Mvc.WebViewPage<List<string>>
    {

#line hidden

        public _Page_Views_Home_Index_cshtml()
        {
        }

        protected ASP.global_asax ApplicationInstance
        {
            get
            {
                return ((ASP.global_asax)(Context.ApplicationInstance));
            }
        }

        public override void Execute()
        {
            WriteLiteral("\r\n");

#line 3 "C:\Users\Robson Ramos\Documents\Visual Studio 2010\Projects\LabMVC\RazorRender\Views\Home\Index.cshtml"
            ViewBag.Title = "Nomes Informados";

#line default
#line hidden

WriteLiteral("\r\n<h2>Lista de Nomes</h2>\r\n\r\n<ul>\r\n\r\n");

#line 9 "C:\Users\Robson Ramos\Documents\Visual Studio 2010\Projects\LabMVC\RazorRender\Views\Home\Index.cshtml"

foreach (var nome in Model)
            {
#line default
#line hidden
                WriteLiteral("        <li>");

#line 12 "C:\Users\Robson Ramos\Documents\Visual Studio 2010\Projects\LabMVC\RazorRender\Views\Home\Index.cshtml"

Write(nome);

#line default
#line hidden
                WriteLiteral("</li>         \r\n");

#line 13 "C:\Users\Robson Ramos\Documents\Visual Studio 2010\Projects\LabMVC\RazorRender\Views\Home\Index.cshtml"

            }

#line default
#line hidden
            WriteLiteral("</ul>");

        }
    }
}

Eureka! Podemos observar que:

1 – A classe gerada deriva de System.Web.Mvc.WebViewPage<List<string>>, onde, List<string> é o nosso Model passado para a View. Se um Model de um tipo diferente fosse passado, o tipo informado seria para a classe System.Web.Mvc.WebViewPage. Assim, o MVC consegue mapear o tipo do Model passado para a View.

2 – A classe possui o nome de _Page_Views_Home_Index_cshtml. Perceba que o path da view gerou o nome da sua respectiva classe, pois, é assim que o Razor mapeia as requests para as instâncias das classes geradas.

3 – No método Execute, podemos perceber como os fragmentos de código Razor contidos na View foram gerados. O que o Razor faz na verdade (a grosso modo) é obter os trechos de códigos pré-fixados com o símbolo @ e expressá-los como declarações C#. Olha que interessante: é por isso que devemos usar o símbolo @ nas nossas Views, pois, o código C# gerado se baseia nisso. Com isso, cada código gerado possui um #line “nº da linha na nossa view” (observe no código acima).

4 – Os elementos HTML da nossa View (as nossas tags) são passadas para o método WriteLiteral, que internamente escreverá o conteúdo dentro de um TextWriter (sim, um TextWriter!). Já o método Write é usado para escrever o conteúdo da coleção (List) no mesmo TextWriter. Assim, é feita a unificação do código C# e HTML.

Se você der uma fuçada a mais naquela pasta observará que há classes para as views _ViewStart e Error também.

Bom, agora o Razor não engana mais ninguém!  É bem legal entender como as coisas funcionam por trás do panos. Espero que tenham entendido e gostado. Por hoje é só pessoal!

Você possui uma definição de pronto?

Jul 24
2011

Esta semana eu estava falando com um amigo meu e ele estava me falando sobre diversos pontos durante o projeto no qual ele estava trabalhando que o incomodava. Entre os pontos citados um me chamou a atenção: trata-se da quantidade de trabalho necessário em diversas tarefas que já haviam sido feitas, o que acabava gerando trabalho remanescente para sprint após sprint. O que mais o incomodava era o fato de que este trabalho já havia sido dado como feito. Oras, se está feito está feito e não se fala mais nisso, certo? Será?!

 

Será que o que havia sido feito estava realmente feito?

 
Vamos ser realistas. Não somos perfeitos. Quem nunca disse a famosa frase:

“A tarefa esta feita, só preciso fazer um pequeno ajuste.”

Será mesmo que este ajuste é realmente pequeno?
Você tem noção exata de quanto tempo este pequeno ajuste custará para o projeto?

No final das contas, este “pequeno ajuste” acaba levando mais tempo do que a tarefa em si. Muitas vezes este pequeno ajuste é na verdade refazer a tarefa completamente. Alguns exemplos clássicos disso são: o código desenvolvido não esta com uma qualidade aceitável, uma refatoração necessária, escrita de testes (o código foi feito sem testes!), atualizar a documentação, correção de algum bug gerado durante a tarefa, subir para produção e etc.
 
O caso acima é um típico cenário onde o time não definiu o significado de pronto. Agora pare e pense: O que para você significa dizer que uma tarefa está pronta? Alguns diriam que pode ser o somente a escrita de código, outros diriam código “commitado” no source control, já outros diriam que pronto é código passando em todos os testes.
 

Ter uma definição de pronto é tão importante assim?

 
Imagine a seguinte situação, um time se compromete a entregar uma quantidade de cenários sprint após sprint baseada na velocidade da sprint anterior. Com isso, na sprint anterior o time conseguiu entregar uma quantidade X de cenários e, portanto, na próxima sprint o time se comprometerá a entregar uma quantidade próxima à quantidade de cenários entregues anteriormente. Ao iniciar a sprint o time descobre que uma série de tarefas não estavam terminadas de fato, assim, para não “queimar o filme” com o product owner decidem que irão terminar todas estas tarefas e ainda entregar com o que se comprometeram.
E o que acontece? O caos se instaura! Para entregar toda essa quantidade de trabalho impossível o time irá então abrir mão de um fator muito importante durante o projeto: a qualidade. Assim, bugs serão introduzidos na aplicação, dívidas técnicas que nunca serão pagas, a relação com os clientes será estremecida, desconfiança, fim da auto-organização e etc.
 
Viu como um simples fator foi responsável por afundar o projeto. Será que a velocidade medida acima estava mesmo sendo medida da forma correta? Portanto, devemos ter conhecimento do que está sendo medido, pois, deve-se conhecer aquilo que se está medindo e o que aquilo significa para todos.
Sendo assim, defina com o seu time o que a palavra pronto significa para todos, entrem em um consenso, chegue a uma definição que todos concordem, faça com que todos saibam que o pronto deve ter passado pelos passos X, Y ou Z e que o resultado gerado é de qualidade.
 
Não se preocupe em achar a melhor definição do mundo sobre pronto, pois, o Scrum é processo adaptativo, se por acaso a definição de pronto não nos atende mais, então, simplesmente definimos outra que esteja dentro da nossa necessidade.
 
Provavelmente depois disso, vocês chegarão a um consenso. O que pronto significa para nós? código escrito, testado, refatorado ,commitado…
 
Só uma dica, você deve ser transparente SEMPRE. Isso mesmo, SEMPRE! Sua integridade e caráter deve valer muito mais do que tarefas e projetos. Muitos projetos falham pela falta de transparência. Ao invés de informar o cliente sobre o possível atraso muitos acabam acobertando os erros existentes pelo mal gerenciamento ou cronogramas impossíveis, portanto, não tenha vergonha de dizer você não conseguirá entregar uma determinada tarefa, afinal, é melhor dizer isso do que dizer: pronto, terminei!

Calendário no MVC com o Datepicker

Jul 21
2011

Uma das necessidades ao mudar de WebForms para MVC é em como compensar a “falta” da quantidade de componentes disponibilizados pelo WebForms. Quando falamos em componentes, muitas pessoas (inclusive eu) já pensam no famoso componente calendar.

 

A biblioteca JQuery UI

 

Para compensar a “falta” de componentes, temos em mão um biblioteca muito poderosa chamada JQuery UI que permite que criemos interfaces poderosas, pois, ela estende as funcionalidades da biblioteca JQuery fornecendo componentes muito bonitos e fáceis de usar.

É uma biblioteca open source, ou seja, temos acesso ao modo como os componentes são criados e podemos customizá-los conforme a nossa necessidade. Lembrando que o Visual Studio fornece suporte intellisense para JavaScript, o que nos ajuda nessa tarefa.

 

Criando a aplicação

 

Crie então uma aplicação ASP NET MVC 3 com o nome de Calendar e selecione o Empty Template. Esta aplicação será bem simples, exibirá um formulário contendo apenas o nome e a data de nascimento para o usuário efetuar o seu cadastro. A seleção da data de nascimento será feita pelo componente de calendário da JQuery UI.

Por padrão as bibliotecas Jquery e Jquery UI já vêm inclusas nos projetos MVC, dentro da pasta Scripts. Conforme abaixo:

 

Visual Studio Project

 

Caso você queira obter a última versão da JQuery UI, podemos efetuar o download no site: http://jqueryui.com/download.

Vamos então criar a nossa classe pessoa, que deverá ser criada dentro da pasta Model do nosso projeto, conforme abaixo:

namespace Calendar.Models
{
    public class Pessoa
    {
        [Required(ErrorMessage = "O campo nome é obrigatório")]
        public string Nome  { get; set; }

        [Required(ErrorMessage = "O campo data de nascimento é obrigatório")]
        [Display(Name = "Data de Nascimento")]
        public DateTime DataDeNascimento { get; set; }
    }
}

Observe que estou usando Data Annotation para efetuar a validação dos dados.

Após isso, adicione um controller ao nosso projeto chamado CadastroController e selecione o template Empty controller, conforme abaixo:

Adicionando um Controller

Após o controller ser criado vamos criar os nossos Action Methods. Então, adicione o código abaixo:

namespace Calendar.Controllers
{
    public class CadastroController : Controller
    {

        public ViewResult Cadastrar()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Cadastrar(Pessoa pessoa)
        {
            if (ModelState.IsValid)
            {
                // Persiste a pessoa no banco ....
                return RedirectToAction("CadastroEfetuado", pessoa);
            }
            return View();
        }

        public string CadastroEfetuado(Pessoa pessoa)
        {
            return string.Format("Obrigado por se cadastrar {0}, lembraremos do seu aniverário no dia {1}",
                                  pessoa.Nome, string.Format("{0:dd/MM}", pessoa.DataDeNascimento));
        }
    }
}

O código acima é bem simples, o método Cadastrar será chamado e a View que exibirá o formulário para o usuário. Após os dados serem preenchidos, o formulário será enviado para o servidor via POST, se tudo estiver preenchido corretamente, efetuamos então a chamada para o método CadastroEfetuado que apenas formata uma string para o usuário. Caso os dados preenchidos não estejam corretos, os erros serão exibidos para o usuário na tela de cadastro.

Após isso, precisamos criar a nossa View, então, clique com o botão direito sobre o método Cadastrar e clique em Add View e selecione a opção para criar uma View tipada. No campo Model class selecione a nossa classe pessoa. Conforme abaixo:

 

Adicionando uma View

 

Com a view criada, adicione o código abaixo:

@model Calendar.Models.Pessoa

@{
    ViewBag.Title = "Cadastrar";
}

<h2>Cadastro de Pessoas</h2>
<script>
    $(function () {
        $("#DataDeNascimento").datepicker();
    });
</script>

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)

    <div class="demo-description">
        @Html.EditorForModel()
    </div>

    <p>
        <input type="submit" value="Cadastrar"/>
    </p>
}

Preste atenção nas tags script no código acima, ela será responsável por acionar o componente Datepicker do JQuery quando o usuário clicar no campo de texto. Além disso, definimos um validation summary para exibir os erros de validação para o usuário.

Datepicker? Sim, o nome do componente de calendário do JQuery UI é Datepicker.

Assim, ao executar a aplicação e acessar o endereço http://localhost:porta/cadastro/cadastrar o formulário abaixo será exibido:

Formulário

Mas, ao clicar no campo Data de Nascimento nada acontece!

 

Adicionando as referências

 

Nada aconteceu porque precisamos adicionar a referência para a biblioteca JQuery UI. Abra o arquivo _Layout.cshtml que está dentro da pasta Shared. É dentro deste arquivo que as nossas views são renderizadas, permitindo criar um layout uniforme para o nosso site.

Adicione a referência para a biblioteca JQuery UI e também a referência para o aquivo css que cuidará do estilo do nosso Datepicker:


<script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.js")" type="text/javascript"></script>

<link href="@Url.Content("~/Content/themes/base/jquery.ui.datepicker.css")" rel="stylesheet"></link>

 

Após isso, execute a aplicação, acesse a Url mostada anteriormente e clique no campo Data de Nascimento.

Formulário

O calendário é exibido e ao selecionar uma data o campo texto recebe a data selecionada. Caso você não goste do estilo do Datepicker, pode customizá-lo no site do Jquery UI e baixar a folha de estilo gerada, substituindo o arquivo css existente.

 

Bug!

 
Ao clicar no botão para submeter o formulário, um erro é exibido na tela:

Formulário

Se você reparar, a data selecionada esta no formato mm/dd/yyyy e é isto que está gerando o erro, pois, o MVC tentará efetuar a conversão deste valor para DateTime e o erro acima será gerado.

Para corrigir o erro acima , basta modificar o formato da data do Datepicker. Então, substitua o script da view criado anteriormente para a versão abaixo:

<script>
    $(function () {
        $("#DataDeNascimento").datepicker({ dateFormat: 'dd/mm/yy' });
    });
</script>

 

Isso irá definir o formato da data. Para maiores detalhes em como customizar o Datepicker sugiro a leitura deste link: http://docs.jquery.com/UI/Datepicker/Localization

Sendo assim, execute a aplicação novamente e preencha os campos do formulário. Repare que agora o formato da data está correto:

Formulário

Efetue o submit do formulário e a mensagem formatada pelo método CadastroEfetuado será exibida na tela. É importante ressaltar que a propriedade DataDeNascimento recebeu a data já convertida (DateTime) que foi selecionada no Datepicker, isto graças ao framework MVC.

Por hoje é só pessoal!

Visit Our Friends!

A few highly recommended friends...

Pages List

General info about this blog...