Postagens

Mostrando postagens de 2013

Evitar duplo submit com jQuery

No trabalho hoje me deparei com a necessidade de impedir que se façam múltiplos submits em uma página Web.

Na empresa onde trabalho não usamos asp.net MVC ou Web Forms, mas sim um framework próprio da empresa, feito sobre asp.net, que lembra muito o asp clássico.

Independente do ambiente ou framework, de ser em php, .net etc, se não houver um recurso nativo para evitar isso então você deve se preocupar: lentidão para enviar a página e o usuário com "dedinho nervoso" clicando em enviar mil vezes por segundo, levando a múltiplos posts (submits) e a inserir mútiplos dados idênticos no seu banco de dados.

Além do trabalho server-side, de validação, prevenção de duplicidades na camada de persistência, redirect para uma página de sucesso etc, deve haver alguma coisa client-side para prevenir o submit duplo.

Com javascript é possível desabilitar o botão no momento do click, e evitar que ele seja pressionado novamente.
Se for um Button do tipo AspButton (System.Web.UI.WebControls.Bu…

Como usar a mesma dll em uma aplicação windows forms e web forms

Imagem
Recentemente me deparei com a seguinte situação em uma aplicação legada: tinha uma dll com as classes de negócio / aplicação, mas essas dlls faziam, de vez em quando, uso do namespace system.web. 

Meu desafio era utilizar estas classes em uma versão windows forms da aplicação, mas isso era impossível, uma vez que com a presença do namespace system.web a aplicação não compilava, e não era permitido a adição da minha dll. 

Você pode estar pensando, e eu também pensei, que o problema se resolveria facilmente adicionando uma referência à dll system.web.dll, mas se fosse só isso o problema estaria resolvido.

O que realmente me causou esse problema era o fato de que quando você cria novas aplicações windows forms ou console, por padrão o visual studio 2010 usa a versão "client profile" do .net framework, uma versão mais magra que não tem toda aquela parafernalha server. No entanto, minha aplicação fazia muito uso de HttpContext.Current.Session.Add, dentro de system.web.dll, que é jus…

Manter a imagem de background fixa

No css, para manter fixa a imagem de background enquanto o texto rola por cima você deve usar o código:

body {background-image: url('fundo.jpg'); background-repeat: no-repeat; background-attachment: fixed }
Caso deseje que a imagem role junto, use:

body {background-image: url('fundo.jpg'); background-repeat: no-repeat; background-attachment: scroll }
Veja o teste abaixo, coloquei o texto em amarelo para que pudesse ser melhor visualizado sobre a imagem:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus vel consequat ligula, et facilisis lacus. Morbi quis auctor ante. Curabitur eros diam, faucibus ut fermentum a, euismod a libero. Duis sed faucibus est. Donec vel dui a dolor luctus luctus. Duis felis turpis, porta vitae nisi et, consequat consequat mi. Praesent enim enim, adipiscing vel dignissim id, adipiscing in neque. Suspendisse vitae lorem elit. Sed quis felis tempor, ornare ipsum id, suscipit justo. Cum sociis natoque penatibus et magnis dis par…

Listar todas as culturas do .net e a configuração corrente

Lidar com culture sempre é um problema, e a conversão de datas e números para strings e vice-versa é pior ainda se o seu sistema permite que usuários de múltiplas culturas imputem a informação da maneira a que estão habituados, ou se você tem dados sensíveis à cultura gravados em campos verchar do banco de dados.
 É importante que as formatações de dados sejam aplicadas à cultura apenas na exibição do dado, mas nunca no seu processamento e armazenamento. Ao gravar no banco de dados, grave sempre o dado bruto em seu formato e tipo de dado padrão (double, integer, datetime etc) usando para isso parâmetros tipados ou o Entity Framework, ou ainda o nHibernate.
 Quando necessário armazenar, por exemplo, uma data como string, então opte por um formato reconhecido internacionalmente, como o padrão ODBC: yyyy-MM-dd (2013-12-02).
Abaixo um programinha console que lista todas as Cultures disponíveis e mostra qual é a corrente configurada no .net.

using System; using System.Collections.Generi…

Fazer uma consulta no SQL Server e enviar o resultado por e-mail, usando C#

Esse é um exemplo em C# que eu sempre passo para todo mundo que está começando na linguagem e quer aprender qualquer coisa um pouco mais complexa do que um "hello world".
Trata-se de um script / função que consulta um banco de dados e devolve o resultado, como um relatório, por e-mail. Então dois temas são abordados: conexão com o banco de dados consultando-o e envio de e-mail.
uso C# para me conectar com um banco de dados MS SQL Server e fazer uma query. O resultado da query é enviado por e-mail, como texto, no corpo do mesmo.
Originalmente escrevi esse programa como exemplo para um colega não programador, que já sabia programar um pouco, porém no VBA do Excel, e que já conhecia o Microsoft SQL Server muito bem e sabia fazer queries e trazê-las para uma planilha excel, mas não conhecia nada de C# e não tinha vivência como programador.

No entanto este tutorial também é destinado à webdesigners que precisam fazer um script para envio de e-mail, mas não querem se aprofundar n…

Testar se uma variável é undefined no javascript

Para testar se uma variável é undefined ou null pode-se compará-la com as palavras chave undefined e null usando os operadores:
== (valor igual),
!= (valor diferente),
=== (estritamente igual, mesmo valor e tipo),
!== (diferente, tipo diferente)

No script abaixo existe uma variável y não declarada. Por causa dela uma exceção é gerada e tratada no catch logo abaixo.

Sempre é necessário verificar se uma variável/objeto é nula ou undefined antes de se usá-la, chamar seus métodos ou alterar suas propriedades.
É a não verificação dessas duas condições que sempre causa erros de script na página (objetos que não existem, que são nulos etc...).

O try ... catch vai garantir que você encontre o erro mesmo que esqueça dessas coisas essenciais, e seu script não para de funcionar, mesmo com erro.
Teste de Undefined var x; try { if(x == null) { document.getElementById('resultado').innerHTML += "x é == null "; } else { document.getEleme…

Wildcards nos seletores JQuery

O JQuery pode ser usado com Wildcards / Coringas nos seletores.

Queria aplicar uma regra de formatação e validação em todos os campos input onde deveriam ser inseridas datas, no entanto, como é um sistema legado, os elementos html não possuem ID's, ou pelo menos não alguns que eu tenha controle. Também não é possível no meu sistema atual atribuir classes aos elementos sem alterar o software que hera o html.

Minha última opção seria confiar nos seletores jQuery e na propriedade name dos inputs. Uma vantagem é que, na minha aplicação, todos os inputs de data tem o prefixo "dt_" no nome. Tudo que eu precisava era de uma forma de selecionar todos os inputs que começavam com "dt_".

O jQuery permite seletores por tipo de tag e atributo, então para selecionar inputs seria $("input[atributo='valor']"). No entanto não existe apenas o operador "=". Os operadores possíveis são:

*= (contém)
$= (termina com)
^= (começa com)

Então, para selecionar…

Deletar todas as tabelas de um banco SQL Server

As vezes, quando estamos desenvolvendo software, precisamos simplesmente apagar todas as tabelas e recriá-las novamente, mas isso é impossível de se fazer caso existam chaves estrangeiras e outras constraints ou dependências dessas tabelas.

Você pode ter tentado o comando EXEC sp_MSForEachtable 'DROP TABLE ?', que é uma stored procedure não documentada que já vem de fábrica com o SQL e que executa um mesmo comando em cada tabela do banco de dados, substituindo ? pelo nome da tabela.
Mais sobre sp_MSForEachtable

Mesmo a sp_MSForEachtable não funcionaria para todas as tabelas. O ideal é que se apague tudo na ordem correta, ou se recrie o banco. Entretanto, se você deseja apagar as tabelas mas permanecer com suas procedures, por exemplo, e rodar o script para recriar as tabelas depois, você pode fazer o seguinte:

1) Conheça a view INFORMATION_SCHEMA.TABLE_CONSTRAINTS. 
Essa é uma  view de sistema que mostra os metadados do banco. No caso, ela lista todas as constraints relacionando…

Uso de memória no SQL Server

O SQL Server, por padrão, tenta colocar o máximo possível de páginas na memória RAM. Esse comportamento é padrão do SQL Server e é o esperado. Isso serve para assegurar o menor tempo de resposta possível na consulta. Logicamente esse comportamento pode ser limitado. Podemos configurar o máximo de memória que o SQL Server pode consumir com paginação, deixando uma margem para outros serviços, no entanto isso não é recomendado pela Microsoft. A recomendação é que o SQL Server seja um servidor dedicado. Recorri à documentação do SQL Server disponível no MSDN e outras fontes para fazer o performance tunning do servidor que eu administro e encontrei um artigo muito esclarecedor, gostaria de compartilhá-lo com vocês: http://www.brentozar.com/archive/2011/09/sysadmins-guide-microsoft-sql-server-memory/ Resumindo:                 1) O sql server sempre tentará usar TODA a memória disponível para cache de páginas                 2) Deveria ser exclusivo Indícios de que você precisa de m…

Delphi Prism, porque não vale a pena

Update
O Prism nunca foi da Embarcadero, ele pertence a Rem Objects, que tinha um contrato com a Embarcadero até esse ano, mas esse contrato já expirou e as duas empresas vão seguir seus caminhos.
O último Delphi Prism foi a versão XE3, se não me engano, mas o Rad Studio XE4 não virá com o Prism, como diz o Andreano Lanusse e o próprio pessoal da Rem Objects.
O Prism foi descontinuado na Embarcadero, mas continuará a evoluir na Rem Objects sob o nome de Oxygene (seu verdadeiro nome).
http://www.andreanolanusse.com/pt/delphi-xe4-conheca-as-novidades-para-ios-e-mais/
http://blogs.remobjects.com/blogs/mh/2013/04/17/p5822
http://www.itwriting.com/blog/7338-no-more-delphi-for-net-prism-removed-from-rad-studio-xe4.html
A partir desse momento a Embarcadero e a RemObjects não são mais parceiras, mas sim concorrentes, mas acredito que o Prism agora irá evoluir, implantando melhorias que não poderia antes devido às políticas da Embarcadero.
Sobre o velho assunto da "Morte do Delphi", eu …

Interfaces no Delphi e destruição prematura de objetos / access violation

Recentemente me perguntaram no site da DevMedia se é correto ou não misturar interfaces e objetos em uma conversão temporária, como esta abaixo:

var C: TCarro; begin C := TCarro.Create; //tenho um objeto, mas C não conta referencias C.Placa := 'ABC1234'; (C as ICarro).Rodar; //converte e roda na mesma linha, mas zera o contador de referencias na proxima linha C.Parar; //isso dá erro Segue links da Thread:
http://www.devmedia.com.br/poo-dominando-o-uso-de-interfaces-revista-clube-delphi-134/22569
http://www.vitorrubio.com.br/downloads/TesteInterfaces.zip
http://www.vitorrubio.com.br/downloads/CD134_Interfaces_V2_Reformulado.zip

Isso por causa do problema de se zerar o contador de referências em interfaces tendo mais uma referência ao objeto em uma variável do tipo objeto e destruir esse objeto prematuramente.

Basicamente nesses casos o comportamento esperado seria um erro.
Pode acontecer de o objeto continuar acessível na memória, ou pelo menos alguns métodos que não us…

Diferença entre Log Shipping, Mirroring e Replication

Li alguns artigos sobre a diferença entre Log Shipping, Mirroring e Replication e gostaria de compartilhar.
http://www.replicationanswers.com/ReplicationLogShippingMirroring.asp
Difference between Log Shipping, Mirroring and Replication
http://simplesql.blogspot.com.br/2011/01/replication-vs-mirroring-and-what-to.html

Basicamente, o Log Shipping é uma estratégia só de Disaster Recovery, mas não muito eficiente para relatórios ou replicação/distribuição dos dados. Ele nada mais faz do que restaurar em uma outra base os logs de transação periodicamente. Esta base fica com lock exclusivo, então consultas nela só podem ser feitas usando-se nolock (dirty reads) ou isolation level snapshot.
Log Shipping restaura o banco inteiro, inclusive tabelas de sistema, views, procedures etc.

Mirroring também é uma solução para Disaster Recovery e funciona para o banco todo, inclusive dados de sistema. Sua vantagem é que pode ser configurado com failover automático, ou seja, para entrar no ar assim que o …