Limitando o conteúdo de uma coluna no DataGrid

by Israel Aece 10. March 2006 20:16

A solução apresentada neste artigo é criar uma coluna customizada para que não se precise alterar a query SQL e também evitar de tratar isso em todo o evento ItemDataBound. A idéia é criar uma coluna que herde diretamente da classe BoundColumn que tem as funcionalidades básicas de uma coluna do DataGrid.

Nesta classe customizada que será criada, uma propriedade chamada QuantidadeCaracteres é criada para receber um número inteiro que será a quantidade de caracteres que a coluna deverá ter. Pelo fato de herdarmos da classe BoundColumn temos acesso e devemos sobrescrever o método FormatDataValue que, é este que recupera o dado da fonte de dados e devolve para o runtime do ASP.NET exibir em seu devido lugar dentro do DataGrid. E para finalizar, a criação de um método adicional chamada Truncar fará o trabalho para "cortar" a string que representa o valor da fonte de dados. Dado esta explicação, veremos abaixo como fica a implementação desta nova classe:

using System;
using System.Web.UI.WebControls;

namespace IAWebControls
{
    public class LimitedColumn : BoundColumn
    {
        private int _quantidadeCaracteres;

        public int QuantidadeCaracteres
        {
            get
            {
                return this._quantidadeCaracteres;
            }
            set
            {
                this._quantidadeCaracteres = value;
            }
        }

        protected override string FormatDataValue(object dataValue)
        {
            return this.Trunca(dataValue.ToString());
        }

        private string Trunca(string originalValue)
        {
            if(originalValue.Length <= this._quantidadeCaracteres)
                return originalValue;
            else
                return string.Format("{0}...", originalValue.Substring(0, this._quantidadeCaracteres));
        }
    }
}

Depois da classe feita, resta utilizá-la no HTML, dentro do DataGrid que iremos colocar na página. Mas vale lembrar que é necessário registrar a classe para que ela funcione corretamente, através da diretiva Register. Finalmente criamos uma coluna dentro do DataGrid que será está coluna que apresentará os dados limitados ao número de caracteres que iremos definir através da propriedade QuantidadeCaracteres. O código abaixo ilustra como isso é configurado.

<%@ Register TagPrefix="IAControls" Namespace="IAWebControls" Assembly="IAWebControls" %>

...

<asp:DataGrid 
    id="DataGrid1" 
    runat="server" 
    AutoGenerateColumns="False">
    <Columns>
        <asp:BoundColumn 
            DataField="CategoryID" 
            HeaderText="CategoryID" />
        <IAControls:LimitedColumn 
            DataField="Description" 
            QuantidadeCaracteres="10" />
    </Columns>
</asp:DataGrid>

 

Tags:

ASP.NET

Paths

by Israel Aece 9. March 2006 09:21

Em um artigo do MSDN.com existe um bom artigo para entender como funcionam os paths de aplicações ASP.NET.

Tags:

ASP.NET

Microsoft Anti-Cross Site Scripting Library V1.0

by Israel Aece 1. March 2006 09:21

Há poucos dias atrás, a Microsoft lançou o "Anti-Cross Site Scripting Library V1.0". Trata-se de uma biblioteca que substitui os métodos HttpUtility.HtmlEncode e HttpUtility.UrlEncode e, com a mesma finalidade, de evitar ataques XSS nas aplicações Web/ASP.NET.

A diferença é que com esta nova biblioteca, os métodos trabalham com os caracteres permitidos "white-listing" ao invés dos caracteres não permitidos "black-listing", como é o caso dos métodos da classe HttpUtility. Isso fará com que, ao chamar os métodos, o que não estiver contido dentro deste "conjunto" de caracteres válidos, será codificado. Para maiores informações a respeito, façam o download e analisem o documento que vem junto com o pacote.

Tags:

ASP.NET | Security

Post Cache Substitution

by Israel Aece 12. February 2006 09:27

Quando colocamos uma determinada página em OutputCache nas versões 1.x do ASP.NET, tínhamos/temos problemas quando existem nesta página, regiões dinamicas que, devem ser sempre atualizadas quando um Refresh ou PostBack acontecer.

Com este cenário, ou teríamos que optar por não deixar a página em OutputCache, ou criar UserControls (arquivos ASCX) para habilitar o Fragment Caching e assim, atualizar essas informações dinamicas. No ASP.NET 2.0 foi introduzido um novo conceito chamado de Post Cache Substitution. Trata-se de um controle chamado Substitution, que temos à disposição na ToolBox do Visual Studio .NET 2005. Devemos arrastá-lo para o local da página onde o conteúdo será dinamico e, através da propriedade MethodName do mesmo, apontamos para um método estático que, obrigatoriamente deverá estar de acordo com o delegate HttpResponseSubstitutionCallback. Este será o método qual o ASP.NET executará sempre.

Abaixo é exibido um exemplo simples que ilustra o funcionamento desta nova feature:

<%@ OutputCache Duration="60" VaryByParam="none" %>
....
<asp:Substitution
     ID="Substitution1" 
     runat="server" 
     MethodName="GetCurrentDateTime" />

<asp:Label
     ID="Label1" 
     runat="server" 
     Text="Label">
</asp:Label>

E no CodeBehind:

    protected void Page_Load(object sender, EventArgs e)
    {
        this.Label1.Text = DateTime.Now.ToString();
    }

    public static string GetCurrentDateTime(HttpContext ctx)
    {
        return DateTime.Now.ToString();
    }

Esse código fará com que a página fique em OutputCache durante 60 segundos, porém a região da página que é determinada pelo controle Substitution, sempre será atualizada.

Tags: ,

ASP.NET

Encriptando seções do Web.Config

by Israel Aece 12. February 2006 09:26

No ASP.NET 2.0, temos uma nova versão do utilitário de linha de comando aspnet_regiis.exe. Consequentemente temos novas funcionalidades adicionadas a ele e, uma delas, é a possibilidade de encriptarmos seções do arquivo Web.Config de uma determinada aplicação ASP.NET. A sua sintaxe para uso é simples:

C:\>aspnet_regiis -prov DataProtectionConfigurationProvider -pef appSettings C:\WebSite1

A seguir a explicação dos parametros:

-prov: indica o provider que quer utilizar para encriptar a seção.
-pef + seção + diretório físico: indica a seção do arquivo Web.Config que será encriptada, fornecendo em seguida, o caminho físico do diretório da aplicação.

Tags:

.NET Framework | ASP.NET | Security

Livro ASP.NET 2.0

by Israel Aece 1. February 2006 09:28

Bem, como já comentei muitas vezes por aqui, já está disponível em algumas livrarias nacionais o Livro de ASP.NET 2.0 do Luis Abreu. Eis aqui uma das opções.

Tags:

ASP.NET | General

Client Side Callbacks

by Israel Aece 9. January 2006 14:16

Um dos principais desafios dos desenvolvedores de aplicações Web é construir uma aplicação intuitiva e ao mesmo tempo dinâmica, tornando a aplicação o mais próximo possível do "mundo Windows". Como essa aproximação é sempre comparada pelos clientes, o principal ponto negativo que as pessoas que estão migrando suas aplicações Windows para aplicações Web encontram é o fato de quando submetemos algo para ser processado no servidor, a página causa um Refresh, ou seja, ela é totalmente reconstruída.

Com esse comportamento as aplicações Web foram bastante crucificadas quando comparadas as aplicações Windows tradicionais. Com a necessidade de ter algo ainda mais dinâmico, algumas tecnologias foram criadas em paralelo as de desenvolvimento dinâmico de sites, tornando as aplicações Web ainda mais interativas. Uma das primeiras tecnologias que apareceram para preencher essa lacuna foi o Remote Scripting, que fornece uma infraestrutura para invocar método server-side, ou seja, que rodam no servidor sem a necessidade de submeter a página. Essa tecnologia utiliza Java Applets para fazer a comunicação com o servidor, comunicando através de protocolo HTTP. Há também opções onde não são necessários Applets para isso, utilizando apenas JavaScript e DHTML, como podemos ver neste componente.

Atualmente, se fala bastante em uma tecnologia chamada AJAX (Asynchronous JavaScript and XML), a qual tem a mesma finalidade da anterior e utiliza o objeto XMLHTTPRequest para a comunicação entre o browser cliente e o servidor. Na versão ASP.NET 2.0, a Microsoft implementou o que chamamos de Client-Side Callbacks. Essa é uma opção paleativa que a Microsoft introduziu no ASP.NET 2.0; paleativa porque a própria Microsoft trabalha atualmente em um projeto chamado Atlas, qual brevemente estará disponível. Esse projeto trará aos desenvolvedores ASP.NET uma facilidade enorme no desenvolvimento, encapsulando boa parte do código Javascript que é requerido nestes cenários. Inclusive serão fornecidos diversos controles Drag & Drop, permitindo assim a codificação declarativamente.

Semelhante ao Remote Scripting, os Client-Side Callbacks permitem chamar um código qualquer VB.NET ou C#, que corre no servidor, através do cliente, sem a necessidade de atualizar a página. A única diferença é que ele utiliza XmlHTTP para se comunicar com o servidor ao invés de Java Applet.

O processo é bastante simples: um determinado controle, do lado do cliente (browser), efetua um pedido, de forma assíncrona, a uma função do servidor através de uma função Javascript que é automaticamente embutida (esta é chamada de WebForm_DoCallback) na página pelo runtime do ASP.NET, e esta por sua vez é responsável por criar e configurar a estrutura necessária para enviar o pedido para o servidor. Depois que a função (embutida pelo ASP.NET) é executada, resta saber como invocar o método Javascript quando a resposta do servidor for retornada (callback). Eis o momento que entra em cena a Interface ICallbackEventHandler.

Esta Interface contém somente dois métodos: RaiseCallbackEvent(string) e GetCallbackResult(). Durante o processo de callback o ciclo de vida da página é um pouco diferente da normalidade, onde todos os eventos serão executados normalmente até o evento PreRender; como esse evento é responsável pela geração do código HTML da página, ele deve ser suprimido. Ao invés de retornar o HTML gerado pelo evento PreRender, é devolvido apenas o retorno do processamento do método GetCallbackResult(). O método RaiseCallbackEvent é invocado anteriormente, depois da conclusão do evento LoadComplete, onde podemos fazer inicializações de objetos, entre outras coisas necessárias para atender à este pedido. O porque de termos dois métodos nesta Interface é justamente para permitir o processamento assíncrono do pedido. Para termos uma idéia do fluxo de processamento de uma página com callback e sem callback, basta analisar a imagem abaixo:

Figura 1 - Fluxo de páginas com e sem callbacks.

Para vermos o funcionamento em um ambiente "quase real", devemos recuperar o nome da pessoa dado um número de C.P.F., ele irá fazer uma pesquisa e, se encontrar alguma pessoa com este código, o nome da mesma será retornado. Claro que isso não reflete exatamente o mundo real, já que nestes casos o ideal seria fazer uma consulta em alguma base de dados. O código abaixo mostra a implementação da Interface ICallbackEventHandler no CodeBehind de uma página ASPX.

public partial class Cadastro : System.Web.UI.Page, ICallbackEventHandler
{
    private string _cpf;
    
    public void RaiseCallbackEvent(string eventArgs)
    {
        this._cpf = eventArgs;
    }

    public string GetCallbackResult()
    {
        if(this._cpf.Length != 11)
            throw new ArgumentException("Comprimento do CPF incorreto.");

        if(this._cpf == "00011122233")
            return "Israel Aece";
        else if(this._cpf == "00011122244")
            return "Juliano Aece";
        else if(this._cpf == "00011122255")
            return "Claudia Fernanda";

        throw new ArgumentException("Registro inexistente.");
    }
}

Como podemos ver no código acima, o CodeBehind da nossa página já está preparado para trabalhar com o processo de callback. Mas somente isso não é necessário: devemos lembrar que o cliente (browser) é responsável por disparar o processo e, quando a função de callback retornar, também deverá receber o resultado, manipulá-lo e, conseqüentemente, apresentar ao usuário. A função que é responsável por disparar o ínicio do processo é chamada de WebForm_DoCallback, pois, como já vimos anteriormente, ela é embutida automaticamente pelo ASP.NET e a única coisa que temos que nos preocupar é quem (controle) e quando (evento) vai disparar esse processo.

Antes de apresentar o código responsável pela geração da função que será colocada no cliente para disparar o callback, é importante conhecer duas novas propriedades introduzidas no ASP.NET 2.0, para manipularmos os callbakcs. A primeira delas, a propriedade SupportsCallback, que está contida dentro de Request.Browser, que retorna um valor verdadeiro ou falso indicando se o browser do cliente suporta ou não os callbacks. Já a segunda é a propriedade IsCallback, que foi adicionada na classe Page que, assim como a propriedade IsPostBack, retorna um valor verdadeiro ou falso indicando se é ou não uma requisição resultante de um processo de callback.

Agora precisamos saber como atribuir a função WebForm_DoCallback em algum evento de um determinado controle no CodeBehind. A classe Page, através de uma nova propriedade chamada ClientScript, fornece um objeto do tipo ClientScriptManager, que este por sua vez, disponibiliza ao desenvolvedor um método chamado GetCallbackEventReference. Este método, dados seus parâmetros (os quais veremos a seguir), retorna uma String que refere-se à uma função client-side que será disparada através de algum evento (também no cliente), que dará início ao processo de callback. Para ilustrar o cenário que descrevemos acima, teremos o seguinte formulário:

Figura 2 - Formulário para os testes de callback.

Como prometido, vamos analisar detalhadamente a função GetCallbackEventReference. A assinatura do mesmo é a seguinte:

public string GetCallbackEventReference (
	string target,
	string argument,
	string clientCallback,
	string context,
	string clientErrorCallback,
	bool useAsync
)

O primeiro parâmetro, target, é o nome do controle de servidor que tratará o callback e o mesmo deve implementar a Interface ICallbackEventHandler. O segundo parâmetro, argument, é um argumento passado do lado cliente para o método do servidor RaiseCallbackEvent, proveniente da Interface ICallbackEventHandler. O terceiro parâmetro, clientCallback, é o nome da função cliente (Javascript) que será disparada quando o callback for processado e retornado para o cliente. Este método tem a responsabilidade de tratar e exibir o resultado. O parâmetro context é um valor que definimos e não é enviado ao servidor, mas é um valor que é passado a todos os métodos cliente. Como algum erro no processamento pode acontecer e uma Exception pode ser lançada, definimos através do parâmetro clientErrorCallback uma função que está também no cliente, que será responsável por tratar algum eventual erro. Finalmente o último dos parâmetros: useAsync; definimos como True se quisermos executar o processo de forma assíncrona e False se quisermos executá-lo de forma síncrona. Agora que já sabemos quais são as funções de cada um dos parâmetros, vejamos como fica o evento Load do WebForm:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsCallback && Request.Browser.SupportsCallback)
    {
        string funcaoJS = this.ClientScript.GetCallbackEventReference(
            this,
            "document.getElementById('" + this.txtCPF.ClientID + "').value",
            "ExibeNome",
            "'Aqui é o contexto.'",
            "TrataErro",
            true);

        this.btnBuscar.OnClientClick = string.Concat(funcaoJS, "; return false;");
    }
}

Com isso, só falta agora no cliente definirmos a função que tratará o retorno do callback e a função que será disparada caso algum Exception ocorrer. O código cliente fica semelhante ao que vemos abaixo:

<script language="javascript">
    function ExibeNome(arg, context)
    {
        document.getElementById('txtNome').value = arg;
    }
    
    function TrataErro(arg, context)
    {
        alert(arg);
        alert('Contexto: ' + context);
    }
</script>

Como podemos ver na figura 3, logo abaixo, o método WebForm_DoCallback foi atribuído no evento onClick do Button, já configurado com os devidos parâmetros que definimos no codebehind através do método GetCallbackEventReference. Para quem não percebeu como o método apareceu no evento onClick do Button, o retorno da função GetCallbackEventReference é atribuído à propriedade OnClientClick do Button que será responsável por iniciar o callback, ou melhor, será responsável por buscar o nome dado um C.P.F..

Figura 3 - Código definido no cliente.

Depois de todas essas configurações realizadas, podemos agora executar algum código no servidor sem a necessidade de atualizar a página. A responsável pela atualização dos dados retornados do callback é uma função Javascript que estará no cliente. É importante dizer que o controle GridView também fornece as funcionalidades de ordenação e paginação dos registros, sem a necessidade de atualizar a página toda. É muito simples colocar em funcionamento essa técnica, bastando apenas marcar a propriedade EnableSortingAndPagingCallbacks como True e a paginação e ordenação do controle GridView passa a ser feita sem a atualização da página como um todo.

CONCLUSÃO: Como pudemos ver no decorrer deste artigo, a Microsoft facilitou o desenvolvimento para trabalhar com o processamento no servidor sem a necessidade de atualizarmos/reconstruirmos a página toda, evitando que se recorra a componentes de terceiros para essa necessidade. Mas vale lembrar que a escrita de código Javascript ainda é necessária, já que depois que o callback é retornado, há necessidade de atualizar partes da página para exibir o resultado ao cliente. Para finalizar, é importante ratificar que a Microsoft está trabalhando em um projeto, chamado Atlas, que permitirá e deixará a codificação mais flexível para esse tipo de utilização.

Tags:

ASP.NET

Encriptando o Viewstate

by Israel Aece 3. January 2006 09:28

Matts Gibbs mostra neste artigo, uma nova funcionalidade do ASP.NET 2.0 para encriptar o viewstate da página. Isso pode ser configurado individualmente para cada página através do atributo ViewStateEncryptionMode ou para todas as páginas da aplicação, definindo isso no arquivo Web.Config.

Tags:

ASP.NET | Security

Powered by BlogEngine.NET 1.5.0.0
Theme by Mads Kristensen

Sobre

Meu nome é Israel Aece e sou especialista em tecnologias de desenvolvimento Microsoft, atuando como desenvolvedor de aplicações para o mercado financeiro utilizando a plataforma .NET. [ Mais ]

Twitter

Indicações

Introdução ao ASP.NET Web API - e-Book