Pesquisar este blog

quinta-feira, 23 de julho de 2015

ASP.NET MVC: EVITE usar HTML Helpers em campos Hidden

Não sou a favor da cópia/plágio de postagens, porém, esbarrei em um problema recentemente que me custou  um bom tempo de pesquisa em busca de uma "resposta" ou justificativa para tal. Em uma aplicação MVC 4.0, uma view de edição possuía dois formulários (duas tags "<form>"). 
O ID da model utilizada pela view era armazenado em hiddens criadas a partir do HTML Helper em ambos os formulários. Notei que após o cadastro da entidade, no retorno do POST da Controller, a model trazia o campo ID preenchido, porém o campo hidden na tela não era preenchido, fazendo com o valor do mesmo ficasse vazio.
Após horas de pesquisa, encontrei em um blog a sugestão de NUNCA utilizar Html Herlpers na criação de campos hidden. Aparentemente não há uma explicação oficial sobre o porque isto ocorre, mas acho interessante disseminar este pequeno inconveniente. Para mais detalhes, acessar o link abaixo:

Fonte: ShivaGaadu

terça-feira, 21 de julho de 2015

Customização de arquivos BAT : Crie arquivos BAT dinâmicamente

Um arquivo BAT é composto por instruções a serem executadas sequencialmente. Sua execução geralmente é agendadas e costuma efetuar tarefas em lote. 
Na maioria dos casos, as tarefas são específicas e dificilmente precisam ser alteradas. Porém, em alguns momentos, é necessário que o arquivo obtenha informações dinâmicas de outras fontes de dados.
E é neste momento que a plataforma .NET se demonstra muito útil! Linguagens de outras plataformas, como Java por exemplo, também são capazes de realizar esta tarefa, porém neste post, utilizaremos a linguagem C# da plataforma .NET. 
Embora o exemplo a seguir seja um tanto quanto simplista, ele permite ter uma ideia do potencial de arquivos bat.
No exemplo a seguir criaremos uma classe dinamicamente e geraremos um arquivo bat responsável pela compilação da mesma, transformando esta em uma dll. Para tal, criaremos um projeto do tipo Console:
A codificação da classe program será a seguinte:
string className = "testeBuild";
string folderPath = @"c:\temp\";
StringBuilder sBuilderClasse = new StringBuilder();
sBuilderClasse.AppendLine("using System;");
sBuilderClasse.AppendLine("namespace CompileViaBatDemo");
sBuilderClasse.AppendLine("{");
sBuilderClasse.AppendLine("     public class " + className);
sBuilderClasse.AppendLine("     {");
sBuilderClasse.AppendLine("         public string Hello { ");
sBuilderClasse.AppendLine("             get {              ");
sBuilderClasse.AppendLine("                 return \"Hi\";");
sBuilderClasse.AppendLine("             } ");
sBuilderClasse.AppendLine("         }");
sBuilderClasse.AppendLine("     }");
sBuilderClasse.AppendLine("}");
File.WriteAllText(string.Format("{0}{1}.cs", folderPath, className), sBuilderClasse.ToString(), Encoding.UTF8);
StringBuilder sBuilderBat = new StringBuilder();
sBuilderBat.AppendLine(@"C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:library " + string.Format("{0}{1}.cs", folderPath, className));
sBuilderBat.AppendLine(@"del " + string.Format("{0}{1}.cs", folderPath, className));
sBuilderBat.AppendLine(@"del " + string.Format("{0}{1}.bat", folderPath, className));
sBuilderBat.AppendLine(@"pause");
File.WriteAllText(string.Format("{0}{1}.bat", folderPath, className), sBuilderBat.ToString(), Encoding.ASCII);
Ao executar este código, será gerado no diretório "c:\temp" nossa classe e o arquivo bat.
Quando o arquivo bat criado é executado, o mesmo gera a dll a partir da compilação da classe, deleta a classe e em seguida a si mesmo.
Ao Importar a dll criada no Visual Studio, é possível consumir sua classe.

quinta-feira, 16 de julho de 2015

JavaScript e OO: Adicionando métodos ao objeto


Na post anterior vimos como criar objetos e manipular suas propriedades através do JavaScript. Porém, "nem só de propriedades viverá um objeto"! Um objeto pode possuir também um ou mais métodos/funções. Por exemplo:

Pensemos num objeto "Carro". Um carro geralmente possui as seguintes características:
  • Ano
  • Cor
  • Fabricante
  • Modelo
Traduzindo estas informações nas propriedades de nosso objeto no JavaScript, teríamos algo mais ou menos assim:
var carro = {
    ano: 0
   ,cor: ""
   ,fabricante: ""
   ,modelo: ""
};
Porém, todo carro que se preze realiza algumas "ações básicas" como:
  • Desligar
  • Ligar
  • Buzinar
No JavaScript, a sintaxe básica para a criação de uma função ou método é: 
function ["nome da função"]([parâmetros]) {
 [Corpo da função]
}
A definição de uma função em um objeto JavaScript não é muito diferente. Abaixo demonstro como seria a implementação das funções necessárias para nosso objeto  (desligar, ligar, buzinar):
var carro = {
    ano: 0
   ,cor: ""
   ,fabricante: ""
   ,modelo: ""
   ,desligar: function(){
       console.log("O carro foi desligado");
   }
   ,ligar: function(){
       console.log("O carro foi ligado");   
   }
   ,buzinar: function(){
       console.log("O carro buzinou");   
   }
}
Após a criação do objeto, para invocar os métodos de nosso objeto, basta utilizar a sintaxe "[objeto].[método]". Ao executar o comando "carro.ligar()", será exibido no console do navegador a mensagem "O carro foi ligado".

terça-feira, 14 de julho de 2015

SQL Server: Auditando alterações no Banco de Dados

Após finalizar os ajustes em um sistema, é chegada a hora de gerar um pacote para publicação. Geralmente o código fonte é armazenado em um controlador de versão, o que facilita na hora de "lembrar" e separar os arquivos que sofreram alterações ao longo do processo de desenvolvimento.
No caso do banco de dados, caso o desenvolvedor não mantenha um controle dos scripts das alterações realizadas no banco de dados, a chance de uma procedure, tabela ou função a ser alterada em produção ser esquecida é muito grande.
Dado este inconveniente, algumas empresas distribuem/comercializam softwares e plugins responsáveis por auditar a base. Ou seja, todas as alterações realizadas nos objetos do banco de dados são registrados e posteriormente é possível obter um script assertivo das mudanças a serem realizadas no ambiente de produção.
Porém, na ausência de um plugin ou software para auditoria das alterações realizadas em base, é possível se guiar pelo objeto sys.all_objects.
Ao realizar a consulta abaixo, o SQL Server traz todos os objetos que foram criados/alterados no banco de dados em relação ao período utilizado no filtro da consulta.
SELECT
    name,
    create_date,
    modify_date
FROM sys.all_objects
WHERE create_date > '[[Data]'
or modify_date > '[Data]'

quinta-feira, 9 de julho de 2015

ASP.NET MVC & Chosen - Parte 1

Conforme prometido, hoje irei mostrar alguns exemplos práticos do uso do plugin Chosen. Neste post irei demonstrar o passo a passo de como utilizar este plugin no Visual Studio utilizando o template ASP.NET MVC. Apenas lembrando que este plugin pode ser utilizado normalmente com HTML e JavaScript/JQuery.

Primeiramente precisamos criar um projeto ASP.NET MVC no Visual Studio:




Feito isso, iremos acrescentar os arquivos CSS e JavaScript que compõe a API nas pastas Content e Scripts:


Criaremos uma Controller responsável por gerenciar as requisições de nossa página de exemplo: 


Nossa controller ficará assim:
using ChosenExample.Web.Models;
using System.Web.Mvc;

namespace ChosenExample.Web.Controllers
{
    public class ChosenExampleController : Controller
    {
        public ActionResult Index()
        {
            return View(new ListHelper());
        }
    }
}
A action Index utilizada na Controller acima, retorna uma View passando nosso objeto Model (ListHelper):
using System.Collections.Generic;

namespace ChosenExample.Web.Models
{
    public class ListHelper
    {
        public int CdAnimal { get; set; }
        public int CdProduto { get; set; }
        public List Animais { get; set; }
        public List Produtos { get; set; }

        public ListHelper()
        {
            FillAnimais();
            FillProdutos();
        }

        private void FillProdutos()
        {
            Produtos = new List();
            Produtos.Add(new Produto() { IdProduto = 1, DsProduto = "Computador" });
            Produtos.Add(new Produto() { IdProduto = 2, DsProduto = "TV" });
            Produtos.Add(new Produto() { IdProduto = 3, DsProduto = "Video Game" });
            Produtos.Add(new Produto() { IdProduto = 4, DsProduto = "DVD Player" });
            Produtos.Add(new Produto() { IdProduto = 5, DsProduto = "Smart Phone" });
            Produtos.Add(new Produto() { IdProduto = 6, DsProduto = "iPhone" });
            Produtos.Add(new Produto() { IdProduto = 7, DsProduto = "Laptop" });
            Produtos.Add(new Produto() { IdProduto = 8, DsProduto = "Janela" });
            Produtos.Add(new Produto() { IdProduto = 9, DsProduto = "Mesa" });
            Produtos.Add(new Produto() { IdProduto = 10, DsProduto = "Lâmpada" });
            Produtos.Add(new Produto() { IdProduto = 11, DsProduto = "Teclado" });
        }

        private void FillAnimais()
        {
            Animais = new List();
            Animais.Add(new Animal() { IdAnimal = 1, DsAnimal = "Cachorro" });
            Animais.Add(new Animal() { IdAnimal = 2, DsAnimal = "Gato" });
            Animais.Add(new Animal() { IdAnimal = 3, DsAnimal = "Pássaro" });
            Animais.Add(new Animal() { IdAnimal = 4, DsAnimal = "Sapo" });
            Animais.Add(new Animal() { IdAnimal = 5, DsAnimal = "Peixe" });
            Animais.Add(new Animal() { IdAnimal = 6, DsAnimal = "Lagarto" });
            Animais.Add(new Animal() { IdAnimal = 7, DsAnimal = "Urso" });
            Animais.Add(new Animal() { IdAnimal = 8, DsAnimal = "Cavalo" });
            Animais.Add(new Animal() { IdAnimal = 9, DsAnimal = "Girafa" });
            Animais.Add(new Animal() { IdAnimal = 10, DsAnimal = "Elefante" });
            Animais.Add(new Animal() { IdAnimal = 11, DsAnimal = "Leão" });
        }
    }
}
As classes abaixo serão utilizadas na tipagem das listas de nossa Model
    public class Produto
    {
        public int IdProduto { get; set; }
        public string DsProduto { get; set; }
    }
    public class Animal
    {
        public int IdAnimal { get; set; }
        public string DsAnimal { get; set; }
    }
Nossa Index (View) conterá dois dropdownlists a serem utilizados em nosso exemplo e um botão a ser utilizado no próximo post.
@model ChosenExample.Web.Models.ListHelper
@{
    ViewBag.Title = "Exemplos";
}


Exemplos Chosen

@Html.DropDownListFor(t => t.CdAnimal, new SelectList(Model.Animais, "IdAnimal", "DsAnimal"), "Selecione", new { multiple = "", @class = "chzn-select search-dropdown chosen-select", data_placeholder = "Selecione", style="width:400px" }) @Html.DropDownListFor(t => t.CdProduto, new SelectList(Model.Produtos, "IdProduto", "DsProduto"), "Selecione", new { @class = "chzn-select search-dropdown chosen-select", data_placeholder = "Selecione", style = "width:400px" }) <input type="submit" name="btnEnviar" value="Enviar" />

Antes de seguir em frente, existem alguns pontos interessantes a serem observados e entendidos:

  1. O atributo multiple = "" indica que o controle será múltipla escolha, tornando possível a seleção de mais de um valor.
  2. A classe search-dropdown habilita a busca no campo


Ao executar a aplicação, o resultado é o seguinte:


Para inicializar o plugin, basta inserir este trecho de código na página dentro da tag script:
$(document).ready(function(){
    $(".chosen-select").chosen()
});
E pronto! Bem diferente da aparência e comportamento padrão não?
Em uma próxima postagem irei abordar o tratamento e manipulação deste campo na Controller.