Translate this page now :



»Programação
»Programação.NET
»Banco de Dados
»Webdesign
»Office
» Certificações Microsoft 4
»Treinamentos4
»Programação 4
»Webdesign«
»Office & User Tips«
»Grupos de Usuários
»Células Acadêmicas«
intcontpiada : 118
Viciado
Você já está cadastrado e participa do grupo de usuários de sua cidade ? Se não, comente o porque.
 
 
Faça um pequeno teste com 10 questões de VB
.:.
Teste seus conhecimentos em Visual Basic, SQL Server e ASP 3.0 com nossas provas on-line
.:.
Aprimore seus conhecimentos em programação com nosso treinamento on-line de lógica de programação
.:.
Veja nosso calendário de treinamentos
Gostou da Página?
Então

para um amigo!
 





Por Dennes Torres
dennes@bufaloinfo.com.br
Dennes Torres possui as certificações MCAD, MCSD,MCSE, MCDBA e MCT. Atualmente atua Como diretor da Búfalo Informática, líder do grupo de usuários DevASPNet no Rio de Janeiro e membro da liderança dos grupos getWindows e devSQL, também do Rio de Janeiro, podendo sempre ser encontrado na lista de discussão do grupo DevASPNet (devaspnet-subscribe@yahoogrupos.com.br) bem como nas reuniões do grupo. Mantém dois blogs em http://cidadaocarioca.blogspot.com

Organizando design e código com .NET

Pesquisa personalizada
Pesquisar Dicas:






A organização de design e código no desenvolvimento para web sempre foi um grande desafio. Na época do ASP 3 ambos ficavam nos mesmos arquivos, arquivos de script, dificultando muito a manutenção tanto do código como do design gráfico.

Com o surgimento do .NET passamos a ter um novo recurso, o code-behind, para permitir a separação do código fonte e das tags HTML para geração do design. Mas a questão é : Será que o code-behind é suficiente para isso ?

Para responder a essa pergunta vou montar aqui uma sequencia de problemas e soluções, chegando então a conclusão de qual seria uma boa solução para uma máxima separação entre código e design gráfico no .NET

Problema : Os sites que construimos possuem diversas partes comuns a todas as páginas, tal como menus, barras laterais, rodapés, assim por diante. O code-behind não resolve isso, então como resolver ?

Solução : Podemos criar cada uma destas partes em arquivos .ASCX, que são chamados de webUserControls. Simplesmente arrastando os arquivos .ASCX para o webForm podemos inserir esses controles nas páginas. Desta forma fica simples garantir a reutilização destes trechos de design.

Fig. 1 : Um Web User Control inserido dentro de um webForm através de Drag And Drop

 

Problema : Como podemos garantir que os pedaços de design separados em web User Controls na solução anterior irão aparecer na exata posição que desejamos ?

Solução : Devemos recorrer ao DHTML e posicionamento de camadas. Montando uma DIV, podemos posicionar o conteúdo do user control no local adequado.

Fig. 2 : Digitação da DIV no código HTML. O Visual Studio auxilia com uma opção Buil Style

 

Fig. 3 : Tela de configuração do position no Buil Style, aberto na digitação da DIV


Problema : Alguns controles, como por exemplo o rodapé da página, não tem uma posição fixa. Devem aparecer imediatamente abaixo do conteúdo da página e o conteúdo varia de tamanho a cada página. Como resolver este problema ?

Solução : Podemos neste caso fazer um design com tabelas e inserir o web user control dentro de uma célula específica da tabela. Assim podemos permitir que o conteúdo, uma célula acima, se expanda, deixando o web user control aparecendo logo abaixo.

Fig. 4 : Os Web User Controls inseridos dentro de uma tabela na página

 

Problema : Em ambas as soluções de posicionamento acima o desenvolvedor ainda tem muito trabalho. No caso das divs, precisa arrastar os controles para cada página que criar, no caso da tabela, precisa criar esta estrutura de tabelas em todas as páginas que criar. Como resolver o problema ?

Solução : O .NET é 100% orientado a objetos, mas ainda não temos herança visual nas páginas. Podemos porém fazer herança de classes e com isso resolver o problema com relação aos Web User Control com Divs. Criamos uma classe base e neste classe carregamos dinamicamente os web user controls. Fazemos então com que todas as páginas da aplicação herdem desta classe base.

Public Class PaginaBase

    Inherits System.Web.UI.Page

 

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)

        Me.Controls.Add(Me.LoadControl("titulo.ascx"))

        MyBase.OnLoad(e)

    End Sub

 

End Class

 

A classe paginaBase herda as características de System.Web.Ui.Page . Fazemos um overrides no método onload para carregar o web user control e tomamos o cuidado de chamar o myBase para que o evento load das páginas continue funcionando

 

Public Class WebForm3

    Inherits PaginaBase

Na montagem dos webForms devemos alterar a herança nos webForms para que herdem da classe criada por nós e não mais de System.Web.Ui.Page

 

Problema : Ao tentar usar a solução acima com um pequeno controle de login ocorreu erro, por que ?

Solução : Porque o carregamento dinâmico dos controles deixa-os fora da tag form. Alguns webControls, tal como o botão e a textbox, não permitem isso. É necessário então corrigir o código para que sejam inseridos dentro da tag form e não fora.

Fig. 5 : Mensagem de erro da inserção de um controle fora da tag Form

 

Public Class PaginaBase

    Inherits System.Web.UI.Page

 

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)

        Dim f As HtmlForm

        f = acharForm()

        f.Controls.Add(Me.LoadControl("titulo.ascx"))

        MyBase.OnLoad(e)

    End Sub

 

    Function acharForm() As Web.UI.HtmlControls.HtmlForm

        Dim obj As Web.UI.Control

        For Each obj In Me.Controls

            If TypeOf obj Is Web.UI.HtmlControls.HtmlForm Then

                Return (obj)

            End If

        Next

    End Function

 

End Class

 

Neste exemplo é criada uma função chamada AcharForm que localiza o formulário dentro da página. Feito isso o Controls.Add é feito com o objeto localizado

Problema : Ok, resolvido o problema do posicionamento com divs, e o caso do posicionamento com tabelas, em que o programador é obrigado a criar as tabelas em todas as páginas que desenvolve ?

Solução : Neste caso pode-se utilizar uma inversão desta arquitetura. Podemos utilizar uma página aspx contendo todo o design e montar o conteúdo das páginas em web User Controls. Com esta arquitetura passamos a ter apenas uma única página ASPX em todo o site, o conteúdo das páginas internas é montado em web user Controls. Os WUCs são carregados dinamicamente a cada chamada. A definição de qual Web User Control carregar pode ser feita com um parâmetro na querystring.

<%@ Page Language="vb" AutoEventWireup="false"  Inherits="WebApplication12.PaginaBase"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

      <HEAD>

            <title>default</title>

            <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">

            <meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">

            <meta name="vs_defaultClientScript" content="JavaScript">

            <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

      </HEAD>

      <body>

            <form id="Form1" method="post" runat="server">

                  <TABLE id="Table1" style="WIDTH: 683px; HEIGHT: 448px" cellSpacing="1" cellPadding="1"

                        width="683" border="1">

                        <TR>

                              <TD style="HEIGHT: 21px" align="center"><A href="default.aspx">Inicio</A></TD>

                              <TD style="HEIGHT: 21px" align="center"><A href="default.aspx?Item=Pagina1">Pagina 1</A></TD>

                              <TD style="HEIGHT: 21px" align="center"><A href="default.aspx?Item=Pagina2">Pagina 2</A></TD>

                              <TD style="HEIGHT: 21px" align="center"><A href="default.aspx?Item=Pagina3">Pagina 3</A></TD>

                        </TR>

                        <TR>

                              <TD vAlign="top" colSpan="4" id="conteudo" runat="server"></TD>

                        </TR>

                  </TABLE>

            </form>

      </body>

</HTML>

 

Eis o código HTML do que seria um design (muito simples, claro) para o nosso exemplo. Observe que esta página não tem code-behind. Ao invés disso fazemos a herança diretamente para a classe PaginaBase. Além disso uma das células da tabela ganhou um runat="Server" e passou a se chamar "conteudo" . Nesta célula irá entrar o conteúdo das páginas, carregado dinamicamente na forma de webControl

 

Public Class PaginaBase

    Inherits System.Web.UI.Page

 

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)

        Dim p As String

        Dim conteudo As HtmlTableCell

 

        p = Request.QueryString("item")

        If p = "" Then

            p = "inicio"

        End If

        p &= ".ascx"

 

        conteudo = Me.FindControl("conteudo")

        conteudo.Controls.Add(Me.LoadControl(p))

        MyBase.OnLoad(e)

    End Sub

 

End Class

 

Muito semelhante ao primeiro exemplo, mas com algumas características a mais : agora utilizamos um findControl para localizarmos o objeto "conteudo" e utilizamos a queryString para obter o nome do controle a ser carregado dinamicamente

 

Problema : Neste caso o usuário irá visualizar os parâmetros na querystring. Tem como evitar isso ?

Solução : Em termos de segurança não, se o usuário desejar ver tais parâmetros, verá. Mas em termos de estética isso pode ser contornado com o uso de frames. Podemos fazer com que a página inicial do site seja uma definição de framews, com um frame de tamanho 0 e o outro ocupando tudo. O usuário nem perceberá que está sendo feito uso de frames, mas o uso de frames ocultará os detalhes da URL que estará sendo chamada.

<frameset rows="0,*" frameborder=no>

      <frame name="header" src="" scrolling="no" noresize frameborder=no>

      <frame name="main" src="default.aspx">

</frameset>

Eis o frameset para ocultar a querystring do usuário do site

 

Problema : Já que estaremos utilizando frames, como resolver um típico problema dos frames - o que fazer para que quando as páginas forem chamadas diretamente elas se desviem para o frame ?

Solução : Podemos utilizar um pouco de javaScript para resolver isso. Inserindo código no evento load da página, podemos testar se a página está sendo carregada fora do frame e, se estiver, podemos desvia-la para a página principal do frame. Precisamos que ocorra uma troca de parâmetros entre as duas para que a página principal do frame saiba qual página foi chamada e assim faça a abertura na página correta.

Layout :

<body leftmargin="0" topmargin="0" onload="if(parent.frames.length==0)
{top.location='inicioframes.aspx?Item=estapagina'}">

Página com os frames :

<frame name="main" src="default.aspx?Item=<%=request.querystring("Item") & ".aspx"%>">

Na página com o layout, inserimos o código javaScript no load do Body para testar se a página está dentro do frame ou não. Se não estiver desviamos para a página com o frame transmitindo um parâmetro. Na página com os frames precisamos receber o parâmetro para carregarmos a página correta.


Conclusão

Vimos então neste artigo 2 soluções : Uma solução especificamente para o trabalho em camadas, fazendo herança de classes; Outra solução mais versátil, utilizando uma arquitetura mais avançada com web user controls.

A solução com classes já é de conhecimento geral e divulgada em vários locais, mas acredito ter criado esta metodologia de montagem do site inteiro com uma página, então se desejarem chama-la de arquitetura BufaloInfo agradeço ;-)

A arquitetura BufaloInfo permite ainda um passo adicional, um avanço com relação a tudo isso : Ao invés do parâmetro na querystring ser o nome de um user control, esse parâmetro pode ser um código. A página base pode ir buscar no banco de dados esse código e recuperar a indicação de qual controle carregar em qual espaço da página.

Além disso a grande vantagem da arquitetura BufaloInfo de design é a total centralização do design gráfico do site. Com esta arquitetura podemos trocar todo o design gráfico do site alterando um único arquivo, sem que o programador se envolva com codificação de design.

Desta forma deixamos o site totalmente dinâmico e reconfigurável, podendo criar uma interface administrativa para redefinir o layout das páginas.

Baixe o código fonte de demonstração da arquitetura BufaloInfo design

Dennes Torres
MCAD,MCSD,MCSE,MCDBA

 



Envie seus comentários sobre este artigo

Nome :

E-mail :

Comentários :


Avise-me quando houverem novos comentários nesta página

Veja abaixo os comentários já enviados :

Nome : Nilton E-Mail : njose@legalonline.com.br
Como evitar que o back do browser refaça uma operação realizada no frame escondido ?
Nome : Nilton E-Mail : njose@legalonline.com.br
Como evitar que o back do browser refaça uma operação realizada no frame escondido ?
Nome : Dennes E-Mail : dennes@bufaloinfo.com.br
Ative o smartNavigation. Além disso pode controlar o cache do browser, pode verificar uma dica sobre isso aqui mesmo no site.
Nome : Wilder E-Mail : wilder_lopes@yahoo.com.br
Olá.
Achei interessante a utilização do método "BufaloInfo". Mas como gerenciar a questão de permissões de acesso no web.config?
Utilizo a forma de autenticação "Forms", e lá, configuro a pasta ou os arquivos aspx que necessitam de login. Tudo é feito automaticamente.
No método "BufaloInfo", é sempre apenas uma página ASPX. O controle de permissões seria manual? Existe alguma forma de resolver isso?
Nome : sergio piter E-Mail : sergiopitern@yahoo.com.br
Dennes utilizando este padrão como faço para que quando o usuario digitar o caminho completo da pagina no browser este desvie para o frame e o frame retorne para a pagina principal sem dar refresh.
Esta ocorrendo isto na minha aplicacao se ele entra com o caminho completo da pagina no browser.
Nome : Márcio Duarte E-Mail : maethorin@fep.com.br
Descupe Dennes, mas eu já tinha usado esse método antes, mas com uma variação, é claro... hehehehe

Eu criei uma página única e ao invés de carregar o conteúdo dentro de um WUC eu fiz um div com runat=server chamado divConteúdo. No codeBehind, de acordo com a QueryString, eu carrego nesse div o conteúdo de um arquivo HTM que cotém o html a ser exibido. Apenas o que deve ser exibido mesmo. Nada de cabeçalhos e tag <body>.

Isso está no site www.fep.com.br, que tem a default.aspx e essa pag.aspx como área aberta.

Para resolver o problema da área restrita, descrito pelo Wilder, eu criei uma pasta e coloquei um web.config nela apenas para dar o deny="?". Nessa pasta está a página que carrega o conteúdo restrito e a login.aspx.

Se quiserem alguma informação, podem mandar um email.

ABS!
Nome : Marilda E-Mail : marilda@eletronuclear.gov.br
Achei sensacional o código, mas como acesso dinamicamente um possível método ou propriedade que se encontra dentro do usercontrol?

Valeu!

Marilda.
Nome : E-Mail :
fun search test!
Nome : 1 E-Mail : 1
-1'
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1