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.

terça-feira, 7 de julho de 2015

JavaScript e OO: Criando objetos

Embora seja uma linguagem fracamente tipada, com o passar do tempo o JavaScript vem ganhando cada vez mais melhorias e funcionalidades. A tipagem desta linguagem facilita a manipulação de suas variáveis e objetos, visto que estes podem ser criados dinamicamente em tempo de execução.
Na maioria das linguagens orientadas a objeto, como Java/C#/C++, o processo de criação de objetos consiste em definir, criar e instanciar uma classe. 
Com o JavaScript não é muito diferente! A vantagem deve-se ao fato de o JavaScript não precisar ser compilado antes da interpretação do script.
Caso fôssemos criar um objeto "Pessoa", utilizando a linguagem C# por exemplo,  o código fonte seria algo mais ou menos assim:
public class Pessoa
{
  public string Nome { get; set; }
  public int Idade { get; set; }
}
No caso do JavaScript, a implementação desta classe poderia ser feita (de modo simplista), da seguinte maneira:
var pessoa = { 
    Nome: ""
  , Idade: 0
};
Devido ao JavaScript ser fracamente tipado, os campos/propriedades da minha classe "pessoa", são inicializados para que os mesmos "assumam" um tipo. No caso da classe C#, os tipos são pré definidos no momento da criação da classe. Para acessar um atributo de minha classe "Pessoa", é necessário primeiramente instanciar a classe e efetuar a chamada através do objeto "p" criado:
Pessoa p = new Pessoa();
//Acesso e imprimo o atributo nome do meu objeto "p"
Console.WriteLine(p.Nome);
Já para o JavaScript, existem outras maneiras de se acessar as propriedades de objetos, chamadas também de notações. Abaixo demonstro duas delas:

1 - Sintaxe de ponto (dot notation): 
A propriedade é acessada assim como no C#, objeto.propriedade:
pessoa.nome = "Bruno";
2 - Sintaxe de colchetes (bracket notation): 
O acesso a propriedade do objeto lembra o acesso a valores em matrizes, objeto["propriedade"]:
pessoa["nome"] = "Bruno"; 
Outro ponto interessante que faz do JavaScript uma linguagem poderosa, é o fato de se poder criar propriedades para objetos existentes em tempo de execução. Nosso objeto "pessoa" até o momento possuia duas propriedades: "nome" e "idade". Caso seja necessário acrescentar uma nova propriedade a este objeto, como por exemplo "peso", basta "acessar a nova propriedade":
pessoa.peso = 70; 
Feito isso, o objeto "pessoa", passa a ter também a propriedade peso. Incrível, não? Para quem desejar se aprofundar mais, encontrei um link interessante bem aqui

quinta-feira, 2 de julho de 2015

Common Language Run-time Integration: crie e utilize métodos .NET em procedures



No desenvolvimento de uma aplicação que realize acesso a base de dados, geralmente a comunicação é unilateral. Ou seja, a aplicação conhece e realiza acessos ao banco de dados, enquanto que o banco de dados desconhece a aplicação.
Dependendo do nível de complexidade da aplicação, visando evitar a repetição de código, parte da lógica da aplicação (regras de negócio) pode ser encapsulada, geralmente em uma DLL.
Quando se conhece o negócio, é possível a manipulação e consulta dos objetos do banco de dados através de procedures e comandos SQL. Porém, quando o acesso a DLL encontra-se ofuscado ou criptografado, fica a questão: e se fosse possível utilizar um método de uma DLL em uma procedure?

Por mais exótica que aparente ser (e é) esta solução, sim, é possível consumir uma DLL e realizar a chamada de seus métodos a partir de uma procedure ou função no banco de dados. Para realizar este acesso, basta seguir os seguintes passos:

Primeiramente é necessário configurar o banco de dados habilitando o CLR e ativar o TRUSTWORTHY:

sp_configure 'clr enable', 1
GO
RECONFIGURE

ALTER DATABASE TreinamentoNET
SET TRUSTWORTHY ON

1 - Abra o Visual Studio e clique em: File > New > Project ...> Visual C# > Windows > Class Library


2 - No menu "Projeto", selecione a opção "Add New Item" e em seguida "Class". 



3 - Segue abaixo a classe utilizada neste exemplo:

using System;
using Microsoft.SqlServer.Server;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Data;
namespace ProcDotNet.Classes
{
    public class ProcedureDotNET
    {
        [SqlProcedure()]
        public static void InsertProduct(SqlString nome, SqlString observacao)
        {
            using (SqlConnection conn = new SqlConnection(@"Data Source = localhost\SQL; Initial Catalog = TreinamentoNET; User ID = sa ; Password = P@$$w0rd"))
            {
                SqlCommand objCommand = new SqlCommand();
                objCommand.Parameters.AddWithValue("@nome", nome);
                objCommand.Parameters.AddWithValue("@observacao", observacao);
                objCommand.CommandText = "INSERT INTO tbProduto (nome, observacao) VALUES (@nome, @observacao)";
                objCommand.Connection = conn;
                conn.Open();
                objCommand.ExecuteNonQuery();
                conn.Close();
            }
        }
    }
}

Na classe acima, o método InsertProduct recebe dois parâmetros e realiza o insert em tabela. É importante lembrar que o projeto class library deve utilizar o framework .NET correspondente a versão suportada pelo SQL Server utilizado. No caso do SQL Server 2008 por exemplo, a versão do framework suportada é a 2.0


Após a compilação do projeto, é necessário registrar a DLL no banco de dados. Para isso, basta executar os scripts abaixo:

CREATE ASSEMBLY ProcedureDotNET
AUTHORIZATION dbo FROM 'C:\Users\bruno\Desktop\ProcDotNet\ProcDotNet.Classes\bin\Debug\ProcDotNet.Classes.dll'
WITH PERMISSION_SET = UNSAFE
GO

Após a execução do script acima, o SQL Server cria um assembly no banco de dados. A partir deste assembly é possível efetuar as chamadas aos métodos da DLL a partir de procedures e funções.
No exemplo abaixo, uma procedure é criada para receber os dois parâmetros requisitados pelo método e invocá-lo: 

CREATE PROCEDURE sp_insert_product
  @nome nvarchar(50),
  @observacao nvarchar(50)
AS EXTERNAL NAME ProcedureDotNET.[ProcDotNet.Classes.ProcedureDotNET].InsertProduct
GO

Feito isso, é chegada a hora de testar nossa criação. Ao executar a procedure enviando os parâmetros, as informações são persistidas na base de dados:

sp_insert_product 'Carro', '4 portas'

Ao realizar uma consulta na tabela, é possível verificar que tudo funciona perfeitamente e que os dados enviados para a procedure foram persistidos:
select * from tbProduto