Categorias
acesso simult??neo application deadlock dicas

Bloqueando apenas um acesso por vez em uma vari??vel de aplica????o

Toda aplica????o web que trabalhamos raramente pensamos na quantidade de acessos que s??o realizados simultaneamente em um determinado trecho de c??digo. Um exemplo cl??ssico ?? uma vari??vel de contador de acessos/visitantes. Armazenamos o valor inicialmente em uma vari??vel de aplica????o. Depois quando um usu??rio acessa, ?? incrementado em 1. S?? que se ao mesmo tempo acessar dois ou mais usu??rios, eles podem capturar o mesmo valor ou valor defasado e colocar a contagem errada. Veja o exemplo abaixo:

Quando tivemos o acesso simult??neoparalelo, o valor capturado da vari??vel da aplica????o foi colhido pelos dois usu??rios e o valor armazenado foi comprometido. Para isso devemos bloquear o acesso ?? vari??vel de aplica????o e permitir apenas um usu??rio por vez executar a soma. Nesse caso, pode-se utilizar o seguinte trecho:

        try
        {
            Application.Lock();
            lock (this)
            {
                // Trecho a ser executado que altera uma vari??vel de aplica????o ou bloco cr??tico
            }
            Application.UnLock();
        }
        catch
        {
            Application.UnLock();
        }

O Application.Lock() ir?? bloquear o acesso de outros usu??rios ??s vari??veis de aplica????o e depois o Application.UnLock() libera. O lock (this) permitir?? apenas o acesso de um ??nico usu??rio por vez no trecho de c??digo cr??tico. A combina????o dos dois m??todos depende muito do que estiver fazendo. Cada caso tem seu respectivo uso. O simples uso do lock (this) pode resolver… Ele ?? muito usado para evitar deadlocks. No mais, s?? isso. Recomendo dar uma lida posteriormente nos artigos abaixo:

Categorias
desempenho dicas dll iis

Diferen??as entre Aplica????es Compiladas e N??o-Compiladas

Quando program??vamos (ou programamos) com aquelas linguagens do tipo PHP ou ASP Cl??ssico apenas peg??vamos o que foi implementado e jog??vamos no servidor web para uso. Com a inova????o das tecnologias e tipos de linguagens (compiladas, interpretadas, h??bridas) algumas d??vidas nos cercam quando estamos publicando um certo projeto. Nesse caso, falemos do ASP.NET para as vers??es acima da 2.0.

Antes de mais nada, o ASP.NET ?? compilado. Mesmo que voc?? jogue os fontes no IIS ele ?? compilado na primeira vez que ?? acessado (e/ou alterado). Voc?? n??o v??, mas por tr??s ?? feito isso. Para quem nunca compilou uma aplica????o web, h?? diversas formas para uma dada finalidade. Geralmente ?? usada a fun????o Publish Web Site (compila e publica).

Mas o que muitos perguntam ??: existe diferen??a de desempenho? N??o! Muitos dizem que h?? um pouco, mas j?? trabalhei com v??rias aplica????es e n??o notei qualquer diferen??a. Li v??rios artigos por a?? na net e n??o achei qualquer um que demonstrasse e/ou notasse diferen??a brusca de desempenho. Ent??o, elaborei a seguinte tabelinha abaixo com um pequeno resumo. Se tiver mais, favor avisar-me que atualizo:

Compilada
N??o-Compilada
 Desempenho
 Normal
Normal
 C??digo-fonte
 Protegido em DLL’s
Vis??vel 
 HTML
 Sem mudan??a
Sem mudan??a 
 Atualiza????oCorre????o
 Precisa compilar todo o projeto e public??-lo (c??digo-fonte) enquanto no design pode alterar normalmente
Pode alterar diretamente no problema (p??gina)
 Primeiro Acesso
 Normal
Lento 

??bvio que toda regra tem sua exce????o, ent??o a depender dos casos supra-citados pode haver pequenos detalhes que mudam uma coisinha ou outra mas nada de t??o dr??stico (de acordo com a tabela – exemplo, na compila????o FULL voc?? n??o altera sequer o HTML). Se quiserem conhecer mais sobre os tipos de compila????o (Full, Pr?? ou Sob-Demanda) visite os links da MSDN e de Dennes Torres.

Categorias
componentes dicas dll imagem pdf thumbnail

Convertendo HTML em PDF

Nesse artigo veremos como converter um HTML em PDF. O HTML pode vir de uma p??gina externa quanto ser criado em tempo de execu????o. N??o haver?? muito o que explicar pois o c??digo em si, voc?? encontra a rodo pela net. Usaremos o componente iTextSharp.

Baixe o bin??rio e adicione em seu aplicativo (pasta Bin). Utilize o c??digo abaixo para fazer o processo de convers??o e exibi????o do PDF na tela:

using System;
using System.Web;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html.simpleparser;

            // Captura ou atribui o HTML a ser convertido – no caso estou baixando de uma URL
            string html = new System.Net.WebClient().DownloadString(“http://thiagomarcal.blogspot.com/”);
            //string html = “Convertendo o HTML em PDF – Thiago Mar??al”;
            // Cria o documento aplicando o tamanho e margens
            Document documento = new Document(PageSize.A4, 80, 50, 30, 65);
            // Memory Stream para ser usado na convers??o e emiss??o
            MemoryStream ms = new MemoryStream();
            // Inicializa o gravador
            PdfWriter writer = PdfWriter.GetInstance(documento, ms);
            // L?? o HTML e atribui
            StringReader conteudo = new StringReader(html);
            // Objeto de convers??o do HTML
            HTMLWorker objeto = new HTMLWorker(documento);
            // Abre o documento
            documento.Open();
            // Aplica o parser para an??lise de convers??o
            // Geralmente aqui ocasiona muitos erros – irei explicar no post
            objeto.Parse(conteudo);
            // Fecha o documento
            documento.Close();
            // For??a o download do PDF gerado – se desej??vel voc?? pode salvar em disco tamb??m
            Response.Clear();
            Response.AddHeader(“content-disposition”, “attachment; filename=Documento_HTML.pdf”);
            Response.ContentType = “application/pdf”;
            Response.Buffer = true;
            Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
            Response.OutputStream.Flush();
            Response.End();

Veja que a vari??vel html eu atribuo o HTML que desejo converter. O seu conte??do pode vir externamente ou posso atribuir um valor desejado.

Vamos aos problemas! Muitos v??o encontrar erro quando o objeto estiver fazendo o parser do HTML e muitos ir??o falhar. Acontece que, devido ?? complexidade do HTML que estiver trabalhando, o componente n??o consegue converter para o formato adequado ao que ele usa internamente. Por exemplo, o TABLE do HTML que usamos ?? “meio” diferente do TABLE que o componente usa. Esse ?? um dos exemplos… Ent??o prepara-se para fazer um tratamento adequado antes de fazer o parser. Eu sugiro o seguinte:

  1. Use express??o regular para validar seu HTML;
  2. Use express??o regular e/ou o HtmlAgilityPack para remover os JavaScripts;
  3. O conte??do a ser convertido deve ser apenas o que est?? dentro do body;
  4. Imagens, CSS e links devem conter o caminho completo (exemplo: http://thiagomarcal.blogspot.com/imgs/logo.png ao inv??s de ../imgs/logo.png), etc.
Ou seja, quanto mais simplificado for seu HTML mais r??pido e f??cil ser?? convertido em PDF. Uma observa????o bem clara ??: nem sempre ficar?? 100% que o esperado.
Uma dica que pode ser usada (e um armengue, claro!) ?? fazer o seguinte:
  1. Gere um thumb (imagem) do HTML que deseja converter (saiba como gerar um thumb de um HTML nesse post) e salve em disco;
  2. Atribua a vari??vel html com o conte??do <img src=”http://thiagomarcal.blogspot.com/imgs/thumb.png” />;
  3. Coloque o width e height na tag IMG o tamanho desejado (pode ser at?? o tamanho do papel).
Pronto! O parser ir?? identificar apenas uma imagem no HTML e gerar?? o PDF com ela. Mole-mole…
Categorias
correios dicas dll web-service

Acompanhar rastreamento de pedido dos Correios com C#

Mais um artigo para quem trabalha com loja virtual… Essa funcionalidade ?? bem importante para visualizar o rastreamento de um determinado pedido. Ao inv??s de mandar apenas o link com o c??digo para seu cliente, porque n??o enviar logo a tabela com os dados? Pois bem, ?? isso que iremos fazer! O c??digo ?? bem simples, r??pido e pode-se alterar para uma “infinidades” de formas afim de o colocar do jeito que deseja.

Abaixo temos um resumo do processo:

  1. Enviamos uma requisi????o GET com o n??mero do rastreamento;
  2. Obtemos os dados de retorno (p??gina completa);
  3. Capturamos apenas a tabela com os dados de rastreamento;
  4. Exibimos na tela.
Para capturar a apenas a tabela com os dados, pode-se fazer de v??rias formas (Express??o Regular, etc), mas preferi usar um componente que captura n??s de um documento HTML, o HtmlAgilityPack. Baixe ele e o coloque na refer??ncia de seu projeto (Bin). Agora ?? f??cil – utilize o c??digo abaixo:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using HtmlAgilityPack;

protected void Page_Load(object sender, EventArgs e)
    {

        // Aplica campos de par??metros
        string codigo = “ES659170465BR”;
        string parametros = “?P_COD_UNI=” + codigo + “&P_LINGUA=001&P_TIPO=001”;
        // Cria o objeto de requisi????o
        WebRequest requisicao = WebRequest.Create(“http://websro.correios.com.br/sro_bin/txect01$.QueryList” + parametros);
        // Realiza a requisi????o
        HttpWebResponse retorno = (HttpWebResponse)requisicao.GetResponse();
        // L?? o objeto e faz a atribui????o ?? vari??vel
        StreamReader stream = new StreamReader(retorno.GetResponseStream(), Encoding.GetEncoding(“ISO-8859-1”));
        string dados = stream.ReadToEnd();
        // Transforma em um documento HTML – HtmlAgilityPack
        HtmlDocument html = new HtmlDocument();
        html.LoadHtml(dados);
        // Captura apenas a tabela contendo os dados do envio
        HtmlNode tabela = html.DocumentNode.SelectSingleNode(“//table”);
        if (tabela != null)
        {
            // Nesse caso voc?? pode capturar as colunas e linhas e trabalhar conforme desejar
            // Apenas fiz o loop para remover a formata????o inicial da tabela
            string htmlTable = “<table>”;
            // Extrai as linhas da tabela
            foreach (HtmlNode linha in tabela.SelectNodes(“//tr”))
                htmlTable += “<tr>” + linha.InnerHtml + “</tr>”;
            htmlTable += “</table>”;
            // Exibe a tabela de rastreamento
            Response.Write(“O hor??rio n??o indica quando a situa????o ocorreu, mas sim quando os dados foram recebidos pelo sistema, exceto no caso do <b>SEDEX 10 e do SEDEX Hoje, </b>em que ele  representa o hor??rio real da entrega.<br><br>” + htmlTable);
        }
        else
            Response.Write(“O nosso sistema n??o possui dados sobre o objeto informado. Se o objeto foi postado recentemente, ?? natural que seus rastros n??o tenham ingressado no sistema, nesse caso, por favor, tente novamente mais tarde. Adicionalmente, verifique se o c??digo digitado est?? correto: “ + codigo);
        // Finaliza objetos
        stream.Close();
        retorno.Close();

    }
No caso peguei o HTML da tabela contendo os dados e exibi de vez na tela. Poderia trat??-la de v??rias formas e uma delas poderia ser transformando-a em um DataTable ou DataSet para alguma manipula????o posterior. Veja nesse link aqui como fazer isso.
Os Correios n??o disp??e de Web-Service para esse tipo de consulta. Olhando na net, encontrei dois artigos: um de Manoel Campos e outro de Carlos Ferrari onde ambos disp??e de Web-Services (em PHP – mas pode ser consumido pelo ASP.NET) para esse tipo de consulta. Quem n??o quiser implementar e apenas consumir, podem us??-los que chega o mesmo objetivo.
Artigo bem f??cil e r??pido! Espero ter ajudado…
Categorias
dicas handler imagem thumbnail

Redimensionar imagens com alta qualidade em ASP.NET

O c??digo que irei mostrar nem precisarei de muita explica????o. Voc?? encontra a rodo a?? pela internet… Contudo, esse tem um pequeno diferencial: misturei o c??digo “pescado” da net com o incremento de Glenn Jones. O redimensionamento consiste em colocar no SRC da imagem o Generic Handler que faz todo o processo e gera a imagem. Ou seja, crie um arquivo ImageResize.ashx e coloque o seguinte c??digo abaixo:

using System;
using System.Drawing;
using System.IO;
using System.Web;


public class ImagemHandler : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {
        
        // Recupera os par??metros passados pela p??gina
        string strSrcImagemOriginal = “../upload/” + context.Request[“img”].ToString();
        string strAlturaImagemRedimensionar = “”;
        string strLarguraImagemRedimensionar = context.Request[“w”].ToString();        
        
        // Cria temporariamnte a imagem
        System.Drawing.Image imagemTemp = System.Drawing.Image.FromFile(context.Server.MapPath(strSrcImagemOriginal));
        
        // Vari??veis contendo o tamanho
        int srcWidth = imagemTemp.Width;
        int srcHeight = imagemTemp.Height;
        int thumbHeight;
        int thumbWidth;
        
        // Redimensiona a largura de forma proporcional
        if (context.Request[“w”] != null)
        {
            thumbWidth = int.Parse(strLarguraImagemRedimensionar);
            thumbHeight = (int)(thumbWidth * imagemTemp.Height) / imagemTemp.Width;
        }
        else
        {
            thumbWidth = imagemTemp.Width;
            thumbHeight = imagemTemp.Height;
        }
        
        // Redimensiona a altura
        if (context.Request[“h”] != null)
        {
            strAlturaImagemRedimensionar = context.Request[“h”].ToString();
            thumbHeight = int.Parse(strAlturaImagemRedimensionar);
            // Faz o rateio para o redimensionamento proporcional
            // Assim a altura e a largura nunca ir??o ultrapassar o tamanho limite
            double widthRatio = (double)imagemTemp.Width / (double)thumbWidth;
            double heightRatio = (double)imagemTemp.Height / (double)thumbHeight;
            double ratio = Math.Max(widthRatio, heightRatio);
            thumbWidth = (int)(imagemTemp.Width / ratio);
            thumbHeight = (int)(imagemTemp.Height / ratio);
        }
        imagemTemp.Dispose();
        
        // Envia para a mem??ria o objeto a ser trabalhado bem como o novo objeto
        Stream objStream = new StreamReader(context.Server.MapPath(strSrcImagemOriginal)).BaseStream;
        BinaryReader objBinaryReader = new BinaryReader(objStream);
        int i = (int)objStream.Length;
        byte[] arrBytes = objBinaryReader.ReadBytes(i);
        System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(arrBytes);
        System.Drawing.Image image = System.Drawing.Image.FromStream(memoryStream);
        System.Drawing.Image thumbnail = new Bitmap(thumbWidth, thumbHeight);
        System.Drawing.Graphics graphic = System.Drawing.Graphics.FromImage(thumbnail);
        
        // Melhoria da nova imagem
        graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
        graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
        
        // Desenha a nova imagem
        graphic.DrawImage(image, 0, 0, thumbWidth, thumbHeight);


        // Aplica a codifica????o necess??ria
        System.Drawing.Imaging.ImageCodecInfo[] info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
        System.Drawing.Imaging.EncoderParameters encoderParameters;
        encoderParameters = new System.Drawing.Imaging.EncoderParameters(1);
        encoderParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
        
        // Exibe a imagem em forma de JPG
        context.Response.ContentType = “image/jpeg”;
        thumbnail.Save(context.Response.OutputStream, info[1], encoderParameters);


    }


}

Mais dado do que isso ?? s?? de m??o beijada!

Categorias
dicas seguran??a

Verificando Vulnerabilidades em Aplica????es Web

Dica r??pida para analisar a seguran??a de aplica????es web… A Locaweb disponibilizou um artigo acerca do uso do WEBSECURIFY (da Google) na qual realiza uma bateria de testes sob uma aplica????o web e exibe as vulnerabilidades que possui. Mais informa????es leiam aqui. Bem interessante…

Categorias
ajax desempenho dicas web.config

Melhorando o desempenho de aplica????es ASP.NET que usam AJAX

Alguns dias atr??s estava lendo alguns artigos sobre desempenho e achei um artigo interessante de LanceZhang na qual ele fez uma bateria de testes em um website que possuia controles ASP.NET AJAX. O artigo voc?? l?? na ??ntegra aqui. Mas, como se diz na web, “?? old mas ?? gold!”, aproveitei o artigo dele para resumir (tirar o quente) das configura????es que ele aplicou e os colocarei aqui. Para quem sabe ingl??s o artigo ?? indispens??vel a leitura, pois l?? ele mostra com detalhes os testes realizados bem como os gr??ficos de desempenho.

Bem, o que ele fez? Encheu uma p??gina de controles AJAX e primeiramente mediu o tr??fego na rede averiguando a quantidade de bytes que s??o carregados quando feito uma requisi????o, sendo ela quando dado um PostBack ou apenas no Load da p??gina. Quem tem o Firefox, com certeza deve ter o plugin Firebug instalado. No Firebug tem uma sess??o de monitoramento de Rede que analisa as chamadas realizadas.

A primeira coisa notada ?? o tamanho da p??gina que estava muito grande. O uso do cache reduzia bruscamente o tamanho da p??gina sem fazer novos carregamentos desnecess??rios. Juntamente com a compress??o do ScriptResource que reduz ainda mais o tamanho dos scripts gerados.  Ent??o, no web.config, devemos aplicar a seguinte configura????o:

<system.web.extensions>
<scripting>
<scriptResourceHandler enableCompression=true enableCaching=true />
</scripting>
</system.web.extensions>

Fa??a um novo teste e notar?? a diferen??a! Outro aplica????o de desempenho ?? a forma como o ScriptManager do AJAX ?? trabalhado. Ent??o ?? sugerido us??-lo com a seguinte configura????o:

<asp:ScriptManager ID=ScriptManagerAjax runat=server EnablePartialRendering=false ScriptMode=Release LoadScriptsBeforeUI=false>
</asp:ScriptManager>

Cuidado com o EnablePartialRendering! Fa??a o teste em sua aplica????o com os valores false ou true porque a depender do que voc?? usa em seu sistema isso muda muito no comportamento dos scripts. Por ??ltimo, voc?? pode usar o CompositeScript dentro do ScriptManager para agregar v??rias chamadas de scripts em uma s??. Veja l?? no site de LanceZhang como fazer, caso tenha interesse nessa parte e se isso ainda n??o foi o suficiente.

Agregado a isso, e fora do escopo, voc?? pode usar a compress??o/compacta????o do ViewState para minimizar o tamanho da p??gina. Voc?? pode encontrar artigos relacionados por a?? na net, mas aconselho dar uma lida nesse aqui ou esse a depender de como queira utilizar. Muitas vezes eu prefiro desabilitar o ViewState… Mais r??pido, s?? que com cautela!

Categorias
dicas dll flash

Flash Control – Componente ASP.NET para Incluir Flash nas P??ginas

Voc?? pode estar se perguntando? Porque usar esse componente ao inv??s de usar embed, object do pr??prio HTML? Bem, abaixo tem uma algumas vantagens de sua utiliza????o:

  • Funciona com o framework 2.0, 3.0, 3.5 e 4.0;
  • Funciona em conjunto com o ASP.NET AJAX;
  • Cross browser;
  • Passagem de vari??veis para o Flash e comunica????o JS, etc.

Essas e outras vantagens o componente lhe d?? para n??o ter dores de cabe??a. O Flash Control ainda lhe resolve o problema do flash sumir quando dado um PostBack. Vamos l??? ?? bem simples seu uso. Primeiro baixe a DLL do componente aqui (h?? 2 vers??es dela: paga e a free – pegue a free). Adicione a DLL FlashControl.dll na pasta Bin de seu projeto. Na p??gina que queira exibir registre a DLL e invoque-a usando os seguintes trechos de c??digos:

<%@ Register Assembly=”FlashControl” Namespace=”Bewise.Web.UI.WebControls” TagPrefix=”Bewise” %>


<Bewise:FlashControl ID=”FlashControlEmbed” runat=”server” MovieUrl=”~/arquivo.swf” BrowserDetection=”False” Height=”200px” Width=”200px” />

Pronto! Mais informa????es e outras op????es (transpar??ncia, FLV, par??metros, etc) podem ser encontradas na p??gina de Faq deles.

Categorias
dicas som windows winform

Tocando/Emitindo som com C#

Dica r??pida para emitir um som com C# usando a API do Windows: basta importar a fun????o PlaySound. Crie a lista enumerada e importe a DLL utilizando os seguintes c??digos:

        // FLAGS DE SOM
        [System.Flags]
        public enum PlaySoundFlags : int
        {
            SND_SYNC = 0x0000,
            SND_ASYNC = 0x0001,
            SND_NODEFAULT = 0x0002,
            SND_LOOP = 0x0008,
            SND_NOSTOP = 0x0010,
            SND_NOWAIT = 0x00002000,
            SND_FILENAME = 0x00020000,
            SND_RESOURCE = 0x00040004
        }


        // IMPORTA????O DO COMPONENTE DE SOM
        [DllImport(“winmm.dll”, EntryPoint = “PlaySound”, SetLastError = true, CharSet = CharSet.Unicode, ThrowOnUnmappableChar = true)]
        private static extern bool PlaySound(string szSound, System.IntPtr hMod, PlaySoundFlags flags);

N??o precisa copiar a DLL para a aplica????o uma vez que ele busca na biblioteca do pr??prio Windows.

Para tocar, execute o m??todo (exemplo):

PlaySound(“sound.wav”, new System.IntPtr(), PlaySoundFlags.SND_ASYNC);

Sempre use a flag PlaySoundFlags.SND_ASYNC (forma ass??ncrona). ?? aconselh??vel usar ela do que PlaySoundFlags.SND_SYNC (forma s??ncrona) se estiver trabalhando com outro processamento em paralelo. Ou seja, ap??s o som, se for realizar algum outro m??todo ou trecho de c??digo. De forma ass??ncrona ele ir?? tocar e continuar com o processamento do c??digo que tiver logo abaixo (paralelo). De forma s??ncrona pode haver lentid??o no processo pois ?? vezes o som pode demorar a tocar ou ter que esperar terminar para prosseguir (cont??nuo). Fa??a os testes antes para ver o diferencial.

Agora sim! Volte ao post do Microterminal e adicione sua fun????o para tocar um som quando apertar * (asterisco).

Categorias
dicas web.config

Problema no ASP.NET Menu no Chrome e Safari

Me veio esse problema a alguns dias ao usar o ASP.NET Menu. Nunca tinha usado para desenvolver menus. Geralmente uso o componente da DevExpress, o ASPxMenu, no qual consiste em um menu robusto, flex??vel e mil vezes melhor que o menu convencional. Pois bem… Quando reparei, vi que no Chrome n??o funcionava… Uai! Procurando informa????es, obtive que o ASP.NET n??o renderiza direito o menu diante desses navegadores e que a solu????o era adicionar uma configura????o de browser na aplica????o. Li v??rios artigos mas s?? Seiti mostrou em seu blog uma forma mais elegante e funcional de corrigir (clique aqui para ver na ??ntegra).

Basicamente, crie a pasta App_Browsers em sua aplica????o e adicione um arquivo safari.browser. Em seguida adicione o trecho abaixo:

<browsers>
    <browser refID=Safari1Plus>
        <controlAdapters>
            <adapter controlType=System.Web.UI.WebControls.Menu adapterType=“” />
        </controlAdapters>
    </browser>
</browsers>

Agora funciona! Mais detalhes veja o blog de Seiti.