Mais acessados

segunda-feira, 24 de março de 2014

ASP.NET MVC - Dicas para não falhar com ASP.NET MVC + Angular JS

O Angular JS é o pop dos Frameworks para desenvolvimento de aplicações SPA (Single Page Application), aparecendo na lista como uma das Most Excited Techology of 2013 na StackOverflow Survey 2013. Este foi criado e, é mantido por Engenheiros da Google e traz um toolbox completo para desenvolver aplicativos fantásticos, criando uma organização natural no projeto e possibilitando extensibilidade por meio de criação de componentes. Outro diferencial é o suporte oferecido pela comunidade, que é bem grande no GoogleDocs e StackOverflow.

Abaixo estão algumas dicas que recolhi por experiência desenvolvendo uma Aplicação complexa a nível Enterprise com ASP.NET MVC e Angular JS.

Não abandone a sua ViewEngine


Passar a responsabilidade de tudo na sua View para o Angular JS é complicado. Você perderá toda flexibilidade e controle que a ViewEngine te proporciona. Deixando esta de lado seu código JavaScript crescerá de maneira assustadora, sendo difícil de rastrear problemas. Além disso, a segurança pode ficar comprometida se você retornar diretamente uma View em HTML estática.

Use os Controllers do MVC e seus filtros para ajudarem nessa parte de segurança e a ViewEngine para popular com alguma informação ou bloquear e sumir conteúdos que necessitam de perfis específicos. A reusabilidade de conteúdo também depende da sua ViewEngine, use ViewBag/ViewData e PartialViews sempre quando necessário. Faça o Angular JS atuar onde ele é bom e não comprometerá sua produtividade.

Não crie directives que herdem $scope


Como um bom iniciante, procure entender o comportamento do $scope dentro de uma Directive. Existem três tipos.
  1. Parent scope você pode fazer iteração entre diretivas.
  2. Child scope herda completamente o scope atual, no caso do controller mais acima, logo é possível setar valores de variáveis do Controller de dentro da diretiva.
  3. Isolated scope, em que a diretiva tem seu próprio $scope e não interage com outro.
Entender esses conceitos é importante. Quando comecei a desenvolver directives não entendia direito e várias das quais criei tiveram que ser refeitas. Não sabia que criando diretivas de Child scope causariam problemas em meus componentes, porque estavam todas ligadas ao mesmo Controller e várias dessas dentro da mesma View causariam concorrência e erros "bizarros" - aprendi da pior forma, "leson learned" :D.

O site do Angular JS não explica bem o conceito, como a maioria dos outros, mas esse post do SackOerflow te dará uma aula completa:

Não use JQuery


O Angular JS vem com uma versão do JQuery embutida, chamada JQLite que disponibiliza as funções básicas da versão full que são mais utilizadas. Existe uma variedade de diretivas que fazem o trabalho do JQuery de maneira muito mais elegante como ng-class, ng-hide, ng-show, ng-selected, ng-disabled, dentre outras.

Mas na hora de construir as suas próprias diretivas será necessário acessar o DOM para interagir com o elementos da View. É aí que entra o JQLite:

Então, nada de scripts JQuery soltos na View ou mesmo dentro do Controller.

Não lute contra o padrão, aprenda MVVM


O MVVM foi criado pelo prodígio do Design Patterns Martin Fowler e o Angular JS foi construído com base nele. De uma maneira geral Angular JS te obriga a seguir um certo padrão para desenvolver a sua aplicação.

Dentro desse padrão está o Controller e $scope que representam sua ViewModel, seu HTML e directives que compõem a View. Não use lógicas absurdas dentro da View usando variáveis do $scope, pois a manutenção vai ficar muito mais difícil. Faça toda a lógica dentro do Controller, e reforçando mais uma vez, sem JQuery.

Aprenda a usar $watch e os interceptadores $http


O $watch possibilita que você observe uma variável qualquer do $scope e execute algum evento caso o seu valor mude. Esse recurso é muito poderoso e pode te economizar centenas de linhas de código para, por exemplo, caso o valor da variável assistida mude esconda, apague ou crie campos dinamicamente na tela.

Do mesmo modo que o $watch, os interceptadores $http podem salvar tempo, possibilitam centralizar validações de erros, habilitar e desabilitar cache, alterar e ler cabeçalhos HTTP e muito mais.

Se você quer mostrar para o usuário uma mensagem de erro amigável toda vez que o seu servidor lançar uma exceção ou uma mensagem específica caso uma validação de campo falhe, os interceptadores são o melhor caminho e você fará uma vez só para ser usada por toda aplicação - Don't repeat yourself.

Herança de controllers existe


Quando seu projeto apresenta muitos padrões, com telas parecidas que executam coisas iguais, a primeira coisa que se pensa é fazer algo reutilizável. Imagine uma tela de inserção que é utilizada em vários cenários, que possuem os mesmos campos e acessam os mesmo dados.

Você pode fazer herança de controllers do Angular JS para facilitar a sua vida. A maneira mais fácil é colocar o controller pai declarado mais externo na View e o controller filho dentro deste. O $scope do pai estará acessível para o filho, sendo possível utilizar de todos os métodos e variáveis. Eu ainda inventei uma maneira de se fazer override dos métodos do controller pai - não sei se isso é legal, se é bonito ou feio, mas salvou minha vida.
//Copio o método original do Controller Pai

$scope.salvarBase = angular.copy($scope.salvar);

//Modifico o método e chamo o base

$scope.salvar = function () {

  //Faço coisas específicas para o Controller Filho]

  $scope.salvarBase();

}

No trecho de código acima eu copio o método original do Controller mais externo, logo depois altero seu comportamento. Por mais feio que seja, funciona e me salvou horas de trabalho.

Não deixe clientes e analistas criarem Fluxos esdrúxulos


Esta é uma parte crítica e bem abstrata do problema, porque dependendo da forma que seu cliente ou analista escreve o Angular JS pode ser um passo para o fracasso. A quantidade de JavaScript que será necessária para escrever seu sistema vai ser absurda - tenho controllers com mais de 2200 linhas de JavaScript devido a pedidos esdrúxulos do cliente.

Não deixe que seu analista crie telas com abas por todos os lados ou fluxos que envolvam chamadas em cascatas de modais que são exibidos a partir de determinados resultados de chamadas assíncronas ao ASP.NET. Irão aparecer erros quase impossíveis de rastrear e o código ficará poluído.

Não deixe a validação por conta do AngularJS


Infelizmente a validação de campos ainda não funciona muito bem, principalmente no IE8/9/10, total fracasso. Deixe tudo que puder no server e use os interceptadores $http que falei anteriormente para exibir os erros para o usuário em um modal, por exemplo.

É possível combinar interceptadores e directive para exibir aquelas famosas validações inline ou em um sumário parecido com o do ASP.NET MVC puro.

Se achar que é muito trabalhoso fazer a sua diretiva, use o clássico jquery-validation para fazer o trabalho duro para você – já aviso que vai perder toda a diversão fazendo sua própria directive =D.

Diga não a versões anteriores ao IE10


O IE7/8/9 como sempre nos acompanha em nossa jornada – desculpe MS, mas é dureza suportá-lo, principalmente com muito JavaScript =(. Se for realmente necessário usar o IE7/8/9, seu cliente for teimoso na verdade, já aviso que terá uma dura jornada.

Cada Controller Angular JS, pode ter certeza, vai ter uma série de trechos de código que só serão executados caso o Browser usado seja IE. No caso das directives, algumas específicas que desenvolvi, foram feitas praticamente duas versões por causa de incompatibilidades.

Um grande problema que enfrentei também foi o cache. Em alguns casos o IE não atualiza a tela de maneira alguma, então existe um cache killer, em que é desabilitado cache de JSON para IE7/8/9 e no interceptador. Chamadas get recebem um timestamp para evitar problemas.

Se você será um sofredor como eu fui, segue abaixo uma série de links que resolverão alguns problemas:

Conclusão


O Angular JS é fantástico, sua aplicação fica com outro nível. Se você tem medo de JavaScript mude de profissão, porque o futuro da Web é Single Page Application.

Abaixo seguem alguns tutoriais de como iniciar em Angular JS + ASP.NET MVC:

Espero que tenham gostado do Artigo. Qualquer dúvida sobre Angular JS e ASP.NET MVC estou a disposição. Meu contato está no blog, me procure.

Boa semana para todos!



sábado, 14 de dezembro de 2013

Windows Phone 8 - Usando HttpClient em um App WP8

O Windows Phone 8 está fenomenal, com cada vez mais recursos e aplicativos. Eu sou um usuário hardcore e considero este o sistema operacional mais estável para mobile. Um app mobile precisa acessar o mundo externo de alguma forma, seja para consultar dados em um serviço ou mesmo enviar informações que serão persistidas em algum lugar. Pensando nisso, foi criado o HttpClient, que facilita a vida de quem precisa acessar Http, como Windows Azure Mobile Services ou consumir Restful services feitos em Web API, por exemplo.

Instalando o HttpClient

O HttpClient está localizado no assembly System.Net.Http.dll e pode ser instalado via Nuget:

  1. Acesse o Nuget Package Manager para instalar um novo pacote.
  2. Procure pelo pacote Microsoft.Net.Http, ele aparecerá como a primeira opção.
  3. Dê dois cliques para instalar o pacote.
Package HttpClient
Com este pacote já é possível usar a classe em sua aplicação, mas com um porém, os métodos dessa classe no WP8 não tem acesso a 100% dos recursos async, o que nos leva a outro passo :).

Instalando o Microsoft Async

Para que os projetos WP8 façam uso de async/await é necessário instalar um pacote Nuget que adiciona métodos extendidos para os tipos que acessam recursos de rede, como por exemplo, o HttpClient.

Para instalar o Microsoft Async:
  1. Acesse o Nuget Package Manager para instalar um novo pacote.
  2. Procure pelo pacote Microsoft Async, ele aparecerá como a primeira opção.
  3. Dê dois cliques para instalar o pacote.
Package com extension method para networking types
Com esse pacote instalado é possível usar o HttpClient com todos os recursos modernos fornecidos pelo .NET.

Exemplo simples de uso do HttpClient

Para usar o HttpClient adicione a referência em sua classe para System.Net.Http. No exemplo abaixo, existe um simples botão, que faz uma chamada Http e coloca o body da request em um textbox.

private async void Button_Click(object sender, RoutedEventArgs e)
{
 HttpClient client = new HttpClient();

 try
 {
  HttpResponseMessage response = await client.GetAsync("http://www.google.com/");
  response.EnsureSuccessStatusCode();
  string responseBody = await response.Content.ReadAsStringAsync();

  this.txtResponse.Text = responseBody;
 }
 catch (HttpRequestException ex)
 {
  throw ex;
 }
}

Veja o uso de async/await sem maiores problemas.

    App usando HttpClient
Ao clicar no botão, é chamado o evento Button_Click, perceba que a requisição retorna status 200.

Código do evento do botão

Como a requisição é para www.google.com, a resposta será o HTML da página, como pode ser visto no textbox:

Textbox é preenchido com o resultado da requisição

Finalizando

O HttpClient está estável e muito fácil de usar. Um problema que tive durante os testes foi a falta de conexão com a internet no emulador do Windows Phone 8 que resolvi usando este post do stackoverflow:
Para maiores referências de como usar o HttpClient nas sua aplicações, um bom lugar para começar é o link abaixo:
Espero que tenham gostado da dica. Bom final de semana para todos!

segunda-feira, 30 de setembro de 2013

ASP.NET MVC - Novidades do ASP.NET MVC 5

São muitas as novidades que virão com o ASP.NET MVC 5 no Visual Studio 2013. Houve uma mudança visual com novo CSS e templates de Scaffold, incorporação do Claims Security, além  da nova camada middleware OWIN. No Visual Studio 2013, a tela para criação do projeto ficou mais inflada, com várias opções de escolha para autenticação e algumas outras perfumarias.

Novo wizard para criar Web App

A tela para criação de projetos ficou um pouco diferente. Agora é possível selecionar WebForms, MVC e Web API, o que adicionará suporte ao que for selecionado. Parece que a Microsoft finalmente resolveu deixar claro que WebForms pode conviver na mesma aplicação que o MVC.


Novo Wizard para criação de Web Apps

Foi adicionado também um novo botão, em que é possível selecionar o tipo de autenticação que a aplicação irá usar.




Dentre as formas de Autenticação estão: Nenhuma, Individual, Windows e para Organizações. Esta última está diretamente ligada a outra novidade que foi adicionada, o Claim Security, que falarei mais tarde.


Novo wizard Scaffold e Bootstrap

Foi criado uma entrada de menu Scaffold para criação de Views/Controllers. Eu particularmente achei que este deviria ficar no menu principal, mas adicionaram como sub item do menu Add.

Menu Scaffold
O processo foi centralizado em um único local, parecido com um wizard de criação de projetos e soluções. Na primeira tela você seleciona o item que deseja, Controller, View, Web API.
Wizard para seleção de item de Scaffold
A próxima tela é bem parecida com as antigas, em que adiciona-se nome do arquivo, modelo, etc, sendo mais um rearranjo de layout, como por exemplo a tela de Views da figura seguinte.


Wizard criação de View
O CSS padrão agora é o Bootstrap. Uma coisa que achei estranha é que a versão do Bootstrap que vem com o template ser a 2.3.1, sendo que a de mercado já é a 3.0.0. Dado que estamos em RC, acho provável que a nova  seja adicionada ao MVC 5 Final- pelo menos espero que sim :).


CSS padrão agora é Bootstrap
Outra coisa importante é que os templates para Scaffold de View criam essas com layout todo baseado no Bootstrap, ficou muito bom!


Segurança com Claims

A segurança para o seu aplicativo agora pode ser ampliada usando Claims. Com isso é possível criar várias formas de autenticação, como os próprios profissionais do ASP.NET Team comentam, ".. é possível criar um Framework de autorização dirigido a qualquer coisa que você saiba que está associado a identidade de uma requisição que estiver sendo efetuada...".


A maior mudança está no arquivo AccountController.cs, como por exemplo, o método de login abaixo, que agora busca IdentityResult, em vez de usuários diretamente como no MVC 4:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        // Validate the password
        IdentityResult result = await IdentityManager.Authentication.CheckPasswordAndSignInAsync(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return RedirectToLocal(returnUrl);
        }
        else
        {
            AddErrors(result);
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

Para saber mais sobre essa novidade sugiro os artigos abaixo:


    OWIN

    O OWIN Open Web Interface for .NET (OWIN) é uma camada intermediária que separa a sua aplicação do Web Server. Com isto é possível migrar facilmente um aplicativo do IIS para um serviço Windows, por exemplo.

    Você notará dois novos arquivos na soluçao, ambos com o prefixo Startup. Estes são os arquivos de configuração do OWIN.

    Arquivos de configuração do OWIN
    Para saber mais sobre o OWIN:

    Entity Framework 6

    O Entity Framework vem em uma nova versão com várias novidades, principalmente melhoria de performace e novos recursos na parte de Migrations - acho excelente esse recurso. No projeto em si a única mudança visível é adição de uma classe IdentityModels.cs.

    O Entity traz agora um contexto próprio para tratar as classes personalizadas de usuário que serão usadas com o Claims Security:


    public class ApplicationUser : User
    {  
    }
    
    public class ApplicationDbContext : IdentityDbContextWithCustomUser
    {
    }
    

    Para saber mais sobre o Entity Framework 6:

    No próximo post vou cobrir mais a fundo as novidades para Web API 2. Espero que tenham gostado! Boa semana para todos!