segunda-feira, 28 de novembro de 2011

Capítulo 5: Input Validation and Site Navigation Lição 3: Using Web Parts

Muitos sites hoje possuem uma coleção de componentes que funcionam sozinhos e são auto-suficientes. Por exemplo, é padrão os sites serem divididos por uma barra lateral de navegação, uma barra no topo com o título, uma barra de rodapé, e uma área com notícias. Além disso muitos portais fornecem hoje componentes e relatórios como exemplo sobre o clima ou cotações financeiras.

ASP.NET Web Parts permite ao desenvolvedor criar estes controles. Com estes controles o usuário do site pode escolher se quer visualizar um relatório na tela, ou tem a opção de remover este controle e adicionar outro de informação do clima. Você pode fornecer ao usuário do site uma coleção de controles, para ele definir qual informação ele quer exibir na página que ele esta visualizando.

What Are Web Parts?

Web Part são componentes pré-definidos com funcionalidades que podem ser adicionados no site. Eles possuem uma estrutura definida, gerenciável e um modelo customizado. Alguns desses componentes podem ser movidos dentro do site para ser posicionado conforme a necessidade do usuário. A figura abaixo mostra um controle Web Part sendo posicionado pelo usário.


Você pode utilizar o controle CatalogZone para adicionar um catalogo de controles em sua página, onde o usuário pode adicionar e/ou remover controles Web Part das regiões pré-definidas. A figura abaixo exibe este cenário onde o usuário visualiza uma lista de controles que ele pode adicionar ou remover de sua página.


Páginas de Web Part podem oferecer ao usuário diversas opções de personalização, isso é ótimo quando você desenvolve funcionalidades que abrangem um público amplo. Veja alguns Web Parts comuns que você pode criar:
  • Uma lista de artigos e notícias
  • Um calendário com os eventos
  • Uma lista de WebSites
  • Uma caixa de pesquisa
  • Controles de Navegação
  • Blog
  • Leitores de RSS, etc...
Qualquer controle seja padrão ou controle personalizado pode se tornar um Web Part, e não necessariamente terá que escrever diversas linhas de código, pois o Visual Studio auxilia nesta tarefa.

The WebParts Namespace

O Asp.Net possui vários Web Parts, são 13 os controles disponíveis na ToolBox do Visual Studio. Esses controles e classes podem ser encontrados dentro da Namespace System.Web.UI.WebControls.WebParts. Algumas dessas classes serão discutidas mais profundamente em lições posteriores. A lista a seguir contém as classes mais importantes:
  • WebPartManager: O controle WebPartManager é necessário em todas as páginas que inclui Web Parts. Ele não tem uma representação visual. Em vez disso, ele gerencia todos os controles de Web Parts e seus eventos na página especificada.
  • CatalogPart: O controle CatalogPart fornece a interface de usuário para gerenciar um grupo de Web Parts que podem ser adicionados a uma página de Web Parts. Este grupo é normalmente todo o site (e não apenas específicos para uma determinada página).
  • PageCatalogPart: O controle PageCatalogPart é semelhante ao controle CatalogPart. No entanto PageCatalogPart são apenas grupos dentro de uma página. Se um usuário fechar uma Web Parte ele pode utilizar o PageCatalogPart para adicionar a Web Parte novamente a página.
  • EditorPart: O controle EditorPart permite aos usuários definir personalizações, como a modificação de propriedades de uma Web Part especifica.
  • DeclarativeCatalogPart: Este controle permite você declarar quais controles Web Parte estão disponíveis para adicionar no site.
  • WebPartZone: Controle utilizado para definir regiões que os controles Web Part podem ser hospedados.
  • EditorZone: Controle que definir a região na página onde pode existir os controles EditorPart.
  • CatalogZone: Defini uma região onde pode existir um controle CatalogPart.
Defining Web Part Zones

Você adiciona Web Parts na página colocando-as em zonas. As Zonas definem a área na página onde o usuário ou o desenvolvedor podem adicionar Web Parts. As zonas possuem as propriedades width, height e um local na página. É possível adicionar uma, nenhuma ou várias Web Parts dentro de uma zona. Veja a figura abaixo:


As zonas permitem definir estilos que serão aplicados a todos Web Parts que estiverem dentro dela. Isto é chamado de Web Part’s chrome. O chrome (cromo) inclui estilos de cabeçalho, estilos de menu, definições de borda e outros. As Web Parts que existiverem dentro de uma zona que teve seu chrome definido irá receber os mesmos estilos.

Você cria zonas de Web Parts com o controle WebPartZone. Este controle define a área onde podem ficar Web Parts, este controle também possui a propriedade HeaderText. Nesta propriedade irá o texto que será exibido ao usuário quando a página e a zona estiverem em modo de edição.

Para definir uma zona, você deve adicionar o controle WebPartZone em sua página, para adicionar controles a esta zona, primeiramente você deve adicionar o controle ZoneTemplate dentro de sua WebPartZone, e dentro deo ZoneTemplate você adiciona os demais controles e combinações de sua Web Part. Veja o código:

<asp:WebPartManager ID="WebPartManager1" runat="server">
</asp:WebPartManager>


<asp:WebPartZone ID="WebPartZoneVendor" runat="server" HeaderText="Vendor Aggregate" style="width: 650px; height: auto">
  <ZoneTemplate>

    <!--Add content to the zone-->

  </ZoneTemplate>
</asp:WebPartZone>


Note nas primeiras linhas desse código a existência do controle WebPartManager, apesar dele não ter uma representação visual para o usuário ele é obrigatório no uso de Web Parts.

Creating Web Parts

Existem três principais métodos de criar ASP.Net Web Parts. O primeiro é criar um user control padrão. O segundo é utilizar um controle ASP.Net como uma Label e definir como sua Web Part. O terceiro é criar um controle customizado que herde da classe WebPart, este terceiro será explicado no capítulo 7 "Creating Custom Web Controls", ele é o método mais demora e mais complicado. Os outros dois métodos são mais simples.

Building Web Parts with User Controls

Para criar uma Web Part baseado em um User Control, basta adicionar o User Controle dentro de uma Web Part Zone que o Asp.Net cuida do restante. Como qualquer User Control basta declara-lo em sua página usando a diretiva @ Register, como a seguir:

<%@ Register src="VendorWebPart.ascx" tagname="VendorWebPart" tagprefix="uc1" %>

Após seu User Controle estar registrado basta adicona-lo a uma Web Part Zone, dentro da declaração ZoneTemplate. Veja abaixo:


<asp:WebPartZone ID="WebPartZone2" runat="server" HeaderText="Fabrikam" style="width: 350px; float: left; height: auto;">

  <ZoneTemplate>
    <uc1:VendorWebPart ID="VendorWebPart1" runat="server" title="Fabrikam" />
  </ZoneTemplate>


</asp:WebPartZone>


Creating a Web Part Control from an Existing ASP.NET Control

Seguindo o modelo de utilizar User Controls, é possível utilizar controles padrões do Asp.Net, basta adiciona-los dentro do elemento ZoneTemplate como foi feito acima. Veja o código abaixo:

<asp:WebPartZone ID="WebPartZone1" runat="server" HeaderText="Vendor Aggregate" style="width: 700px; height: auto">
  <ZoneTemplate>
    <asp:Label ID="Label3" runat="server" Text="" title="Vendor Totals">
      <div style="margin-top: 12px; margin-bottom: 20px; line-height: 30px; font-size: 12pt">
        Total Active Users: <a href="#">21</a>
        <br />Total transactions today: <a href="#">166</a>
        <br />Revenue trades to-date: <a href="#">$34,450</a>
      </div>
    </asp:Label>
  </ZoneTemplate>
</asp:WebPartZone>


Enabling Users to Arrange and Edit Web Parts

Web Parts podem ser exibidas de diferentes formas. O modo como ela é exibida é indiferente do que o usuário esta fazendo com a Web Parts ou onde ela esta hospedada naquele momento. É possível alterar o modo de exibição das Web Parts utilizando o controle WebPartManager. Basta definir a propriedade DisplayMode, as opções disponíveis para esta propriedade são:
  • BrowseDisplayMode: É a forma padrão que os usuários navegam;
  • DesignDisplayMode: É o modo que permite aos usuários arrastar a Web Part para diferentes locais;
  • EditDisplayMode: Parecido com o DesignDisplayMode, permite aos usuários arrastar a Web Part, e além disso permite também editar os dados como título, tamanho, direção, aparência da janela e zona, utilizando os controles AppearanceEditorPart e LayoutEditorPart. Para utilizar este modo é necessário adicionar o controle EditorZone a sua página e em seguida o controle AppearanceEditorPart e/ou LayoutEditorPart;
  • CatalogDisplayMode:  Permite ao usuário adicionar Web Parts que você especificou no controle CatalogZone. Para utilizar este modo é necessário ter o controle CatalogZone em sua página;
  • ConnectDisplayMode: Permite ao usuário estabelecer conexões manualmente entre os controles usando o controle ConnectionZone. Por exemplo uma Web Part pode ser ligada para mostrar informações de resumo e detalhe de um relatório. Para utilizar este modo é necessário ter o controle ConnectionZone em sua página.
O código a seguir exibe no clique de um botão como alterar o modo de exibição de uma Web Part:

protected void ButtonEdit_Click(object sender, EventArgs e)
{
  string mode = (string)ViewState["mode"];
  //switch modes
  if (mode == "browse")
  {
    ViewState["mode"] = "edit";
    ButtonEdit.Text = "Done";
    WebPartManager1.DisplayMode = WebPartManager1.SupportedDisplayModes["Catalog"];
  }
  else
  {
    ViewState["mode"] = "browse";
    ButtonEdit.Text = "Edit";
    WebPartManager1.DisplayMode = WebPartManager1.SupportedDisplayModes["Browse"];
  }
}


Repare que é usado a coleção SupportedDisplayModes para definir qual modo será exibido. Neste código vale explicar que o valor da ViewState foi salvo no evento PageLoad.

Connecting Web Parts

Uma possibilidade poderosa da Web Part é a conexão entre Web Parts. Para entender o uso, imagine o cenário onde esta desenvolvendo uma aplicação para controle da folha de pagamento dos funcionários, onde você tem:
  • A Web Part principal onde o usuário navega entre os funcionários.
  • Uma Web Part que exibe um gráfico das horas extras pagas ao funcionário.
  • Uma Web Part que exibe um gráfico de pizza que exibe o valor da folha de pagamento, benefícios e pensões que se encaixam no perfil global do funcionário.
  • E uma Web Part que compara o salário do funcionário com outros funcionários do mesmo cargo.
Com a conexão de todas Web Parts o usuário irá selecionar o funcionário uma única vez e todas as outras Web Parts irão ter suas informações atualizadas automaticamente.

Outro cenário é o desenvolvimento de um portal onde você tem várias Web Parts com informações distintas como clima, notícias locais e localização de bares. Porém todas elas necessitam do CEP para localizar essas informações, o usuário do portal irá informar o CEP uma única vez e todas as Web Parts irão se comunicar para ter acesso a este CEP.

Creating a Static Connection

Conexões podem ser estáticas ou dinâmicas. Se a conexão for estática, estabelecidade pelo desenvolver no momento de desenvolvimento ela não poderá ser alterada ou excluida pelo usuário. Conexões estáticas envolvem um Provider e um ou mais WebParts consumidores. Veja os passos para se criar os controles, tanto o provider como o consumidor e estabelecer uma conexão entre eles.

Primeiro Passo: Criar o WebParte provider.
O WebPart provider pode derivar da classe WebPart ou ser um user control. Você deve criar no seu WebPart um método público que tenha o atributo ConnectionProvider. Este método deve retornar o valor que o WebPart consumidor irá receber. Veja o código:

public partial class Provider : System.Web.UI.UserControl
{
  string _textBoxValue = "";
  

  [ConnectionProvider("TextBox provider", "GetTextBoxValue")]
  string GetTextBoxValue()
  {
    return _textBoxValue;
  }
 

  protected void Button1_Click(object sender, EventArgs e)
  {
    _textBoxValue = TextBoxProvider.Text;
  }
}


Passo 2: Criar o WebPart consumidor.
Assim como o provider pode herdar de WebPart ou ser um user control. É necessário criar um método público que possua o atributo ConnectionConsumer que recebe o mesmo tipo que o método do ConnectionProvider retorna. Veja o código:

public partial class Consumer : System.Web.UI.UserControl
{
  [ConnectionConsumer("TextBox consumer", "ShowTextBoxValue")]
  void ShowTextBoxValue(string textBoxValue)
  {
    LabelConsumer.Text = textBoxValue;
  }
}


Passo 3: Crie uma WebPage e adicione o controle WebPartManager, em seguida adicione o container WebPartZone.

Passo 4: Adicione seus WebPart ao WebPartZone, tanto o provider como o consumidor:

<asp:WebPartZone ID="WebPartZoneProvider" runat="server" Height="400px" Width="300px">
  <ZoneTemplate>
    <uc1:Provider ID="Provider1" runat="server" title="Provider" />
    <uc2:Consumer ID="Consumer1" runat="server" title="Consumer" />
  </ZoneTemplate>
</asp:WebPartZone>


O próximo passo é estabelecer a conexão entre os dois controles. Adicione o elemento <StaticConnections> ao WebPartManager e dentro deste elemento adicione o controle WebPartConnection para declarar sua conexão.

O controle WebPartConnection deve ter a propriedade ID, a propriedade ProviderID identifica o controle provider, ProviderConnectionPointID identifica o método do provider, ConsumerID identifica o controle consumidor, ConsumerConnectionPointID identifica o método no consumidor. Veja o código:

<asp:WebPartManager ID="WebPartManager1" runat="server">
  <StaticConnections>
    <asp:webPartConnection
        ID="conn1"
        ProviderID="Provider1"
        ProviderConnectionPointID="GetTextBoxValue"
        ConsumerID="Consumer1"
        ConsumerConnectionPointID="ShowTextBoxValue" />
  </StaticConnections>
</asp:WebPartManager>


Repare que você deve criar um controle WebPartConnection para cada par de controle conectado.

Enabling Dynamic Connections

Conexões dinâmicas podem ser estabelecidades pelo usuário. Para permitir esta ação você precisa adicionar o controle ConnectionsZone em sua página.
Para permitir que os usuários criem ou parem conexões, siga os seguintes passos:
  1. Crie uma página com um provider e um consumidor como explicado anteriormente.
  2. Opcionalmente, estabeleça uma conexão estática entre o provider e o consumidor. Esta será uma conexão padrão que estará sempre disponível para o usuário, mas ele pode modificar criar ou parar outras conexões dinâmicas.
  3. Adicione o controle ConnectionsZone em sua página.
  4. Adiciona o controle para permitir que o usuário entre no Modo Connect como explicado anteriormente em "“Enabling Users to Arrange and Edit Web Parts".
Establishing Dynamic Connections Among Web Parts

Quando um usuário acessar sua página ele pode alterar para o modo de conexão e utilizar o controle ConnectionsZone para editar as conexões. Veja os passsos:
  1. Altere o modo de visualização para connect.
  2. O menu do WebPart irá aparecer entre o provider e consumidor, clique em Connect no menu, veja a imagem:

        3. Irá aparecer o objeto ConnectionsZone:

        4.Caso já exista uma conexão, clique em Disconnect para fechar esta conexão. Em seguida clique em Create A Connection To A Consumer, selecione o consumidor e clique em Connect:

        5.Quando finalizar a edição das conexões clique em Close. As WebParts estarão conectadas como se fosse feito estaticamente.

Personalizing Web Parts

WebParts suportam personalização. A personalização permite que as alterações feitas sejam armazenadas por cada usuário, permitindo que ele visualize a página da mesma forma na próxima visita. Personalização de WebParts dependem dos cookies do navegador do usuário, através das informações dos cookies, serão buscadas as personalizaçãoes feitas no banco de dados. Armazenada essas informações por usuário, normalmente você vai querer utilizar autenticação, mas isso não é necessário.

Enabling Personalization for Custom Controls

Para permitir esta personalização nos controles de WebPart é necessário definir no método público do controle o atributo Personalizable, veja como:

[Personalizable]
public string PostalCode
{
  get
  {
    Return _postalCode;
  }
  set
  {
    _postalCode = value;
  }
}

Enabling Shared Personalization

A personalização de WebParts são habilitadas por padrão e os usuários autenticados, conseguem personalizar uma WebPart sem qualquer configuração especial. Porém essas personalizações são feitas a nível de usuário, onde cada usuário visualiza somente sua mudança.
Caso queria dar permissão para algum usuário, como o webmaster do site altere a personalização de qualquer usuário, isto é possível. Basta habilitar a personalização compartilhada no web.config.

Dentro da sessão <system.web>, adicione a sessão <authorization>, então adicione o elemento <allow> para especificar qual usuário ou usuário tem acesso a personalização compartilhada.

<authorization>
  <allow verbs="enterSharedScope" users="SomeUserAccount" roles="admin" />
</authorization>

Desta forma os usuários podem alterar uma personalização e essas mudanças serão vistas por outros usuários.
Disabling Personalization for a Page

Caso queria desabilitar a personalização em alguma página, basta definir a propriedade WebPartManager.Personalization.Enabled para false. Veja como:

<asp:webPartManager ID="webPartManager1" runat="server">
  <Personalization Enabled="False" />
</asp:webPartManager>

sexta-feira, 4 de novembro de 2011

Capítulo 5: Input Validation and Site Navigation Lição 2: Performing Site Navigation

Os sites devem prover aos usuários formas simples de navegação. Os desenvolvedores devem controlar como o usuário navega em seu site e até mesmo as execuções de PostBack em suas páginas. Esta lição mostra ferramentas que auxiliam nessas tarefas.

Is Page Navigation Necessary?

Navegação entre páginas é o processo de passagem de uma página para outra. Entretanto com alguns recursos que temos atualmente como Asynchronous JavaScript e XML (AJAX), você pode executar vários processos na mesma página, sem a necessidade de ficar trocando de páginas. Você não precisa mais ficar trocando de páginas para executar algo, pode fazer isso com um PostBack para o servidor ou até mesmo do lado do cliente. Claro que existem cenários que será necessário o armazenamento em banco de dados ou coisas do tipos.

Mas é importante que saiba que hoje dependendo do cenário pode fugir de metodologias antigas de navegação entre páginas para gerenciar processos.

Choosing a Method to Navigate Pages

O asp.net possui algumas maneiras de navegar entre as páginas. É bom conhecer detalhamente as diferenças entre cada maneira. Veja as opções disponíveis:
  • Client-side navigation: um código cliente permite que seja solicitado uma nova página. Este código solicita uma nova página com base no evento de um hyperlink ou a execução de um JavaScript;
  • Cross-page posting: um controle e um formulário são configurados para enviar um PostBack para uma página diferente da que faz a solicitação;
  • Client-side browser redirect: um código servidor, envia uma mensagem ao navegador solicitando uma página diferente;
  • Server-side transfer: um código servidor solicita uma transferência para uma página diferente;
Client-Side Navigation

A forma mais simples de permitir a navegação entre as páginas do seu site é utilizar um controle de Hyperlink, basta definir a propriedade NavigateUrl com o destino do link. O controle asp.net Hyperlink quando renderizado, gera o elemento html <a>, veja o exemplo:


HyperLink Control: Source
<asp:HyperLink ID="HyperLink1"runat="server" NavigateUrl="~/NavigateTest2.aspx">Goto NavigateTest2</asp:HyperLink>

HyperLink Control: Rendered HTML
<a id="HyperLink1" href="NavigateTest2.aspx">Goto NavigateTest2</a>

No exemplo acima quando este link for clicado o navegador requisitará a página NavigateTest2.aspx, neste caso não estamos passando nenhum informação de dados na URL, mas podemos utilizar a querystring para fornecer algumas informações caso necessário.

Outra forma de se fazer o mesmo processo é via javascript. O objeto document representa o formulário atual no javascript. Podemos definir a propriedade location para requisitar a nova página. Veja o exemplo:

<input id="Button1" type="button" value="Goto NavigateTest2" onclick="return Button1_onclick()" />

Quando o botão for clicado ele irá acionar uma função javascript chamada Button1_onclick(), esta função deve ser criada dentro da tag <head>:

<script language="javascript" type="text/javascript">
  function Button1_onclick() {
    document.location="NavigateTest2.aspx";
  }
</script>


Cross-Page Posting

 Cross-Page Posting, ou postagem entra páginas é frequentamente usado em cenários onde por exemplo existem 2 páginas, a primeira com um formulário e a segunda utilizada para exibir os dados. Na primeira basta definir a propriedade PostBackUrl de um botão com o nome da segunda página, chamada de página de processamento. Esta página recebe o PostBack com os dados da primeira página para executar o processamento.


Nesta página de processamento é possível validar se ocorreu o PostBack na página anterior enviando uma coleção de dados. Através da propriedade Page.PreviousPage, você valida se ocorreu ou não o PostBack, veja o exemplo a baixo:


protected void Page_Load(object sender, EventArgs e)
{
  if(Page.PreviousPage == null)
  {
    LabelData.Text = "No previous page in post";
  }
  else
  {
    LabelData.Text = Server.HtmlEncode(((TextBox)PreviousPage.FindControl("TextBox1")).Text);
  }
}


Accessing Posted Data as Strongly Typed Data

É possível acessar propriedades com tipos definidos entre páginas, sem a necessidade de chamar o FindControl ou executar alguma conversão. Você pode criar uma propriedade pública na sua primeira página que terá seu valor acessado pela segunda página. Além de criar esta propriedade na primeira página, só é necessário adicionar a diretira PreviousPageType na segunda página, a página de processamento.

Imaginando o mesmo cenário do exemplo anterior, na primeira página chamada DataCollection.aspx temos um textbox e um botão onde sua propriedade PostBackUrl foi definida como "~/ProcessingPage.aspx". Crie a seguinte propriedade na primeira página:

public string PageData
{
  get { return TextBox1.Text; }
}


Para ter acesso a esta propriedade na página de processamento, adicionar a diretiva PreviousPageType, como a seguir:
 <%@ PreviousPageType VirtualPath="~/ProcessingPage.aspx" %>

Na página de processamento temos uma label que irá exibir a propriedade da página anterior:

protected void Page_Load(object sender, EventArgs e)
{
  if (PreviousPage == null)
  {
    LabelData.Text = "No previous page in post";
  }
  else
  {
    LabelData.Text = PreviousPage.PageData;
  }


Acessando a propriedade PreviousPage.PageData conseguirá ter acesso ao valor do textbox da página anterior. Desta forma é possível declarar outras propriedade, fugindo da necessidade de conversões ou a chamada ao FindControl.


Client-Side Browser Redirect

Este é o famoso Response.Redirect que usamos. Diversas vezes precisamos redirecionar o usuário a uma outra página com base em uma ação que ele executou no site. O objeto Page.Response contém o método Redirect que faz isso.

O Redirect é executado do lado do servidor, porém não é um PostBack, ele ocorre após o PostBack. Considere o exemplo que você possui uma página SubmitOrder.aspx que contém um botão que irá ocasionar um PostBack no servidor, após este PostBack você irá redirecionar o usuário a página OrderDetails.aspx

protected void ButtonSubmit_Click(object sender, EventArgs e)
{
  Response.Redirect("~/OrderDetails.aspx");
}


O redirecionamento ocorre por que é enviado para o browser o código de resposta 302 junto com o novo endereço url. Assim a url do navegador é alterada e o usuário é redirecionado para a nova página. É necessário utilizar em momento certos, pois como é executado do lado do servidor, existe um "custo" para realizar esta operação.

A propriedade PreviousPage não é alimentado neste caso, para acessar dados da página anterior é necessário utilizar outras fomas como armazenar em Cookie, variáveis de Sessão ou via QueryString.

Server-Side Transfer

Você pode usar a Server.Transfer para forçar o Asp.Net a processar uma página diferente da informada na URL sem a necessidade de uma nova requisição no browser. Por exemplo, se você acessa uma página page1.aspx e nessa page1.aspx ela executa Page.Server.Transfer("page2.aspx") o Asp.Net irá processar e exibir a página page2.aspx, porém para o usário isso será invisivel e na URL do navegador continuará aparecendo page1.aspx. Exemplo de código:

protected void Button1_Click(object sender, EventArgs e)
{
  Server.Transfer("~/OrderProcessing.aspx", false);
}


O método Transfer possui uma sobrecarga que possui um parâmetro boleano chamado preserveForm. O valor informado para este parâmetro indica se você quer manter seu formulário e os dados de query string. É possível acessar a propriedade PreviousPage durante a transferência. Se ocorrer alguma excessão na nova página que foi chamada, o processo irá retornar a página original.

Este capítulo faz questão de salientar que o uso do Server.Transfer é mais importante do que parece. Ele é útil quando você quer por exemplo navegar entre diferentes páginas no seu site, mas exibir apenas uma URL ao usuário.

O "poder" do Server.Transfer esta em você alternar suas páginas sem que o usuário veja isto.


Using the Site Map Web Server Control


Já foram explicada técnicas de como ajudar o usuário movimentado-o entre as páginas. Um quesito importante no seu website é uma estrutura sólida de navegação que auxilia e facilita o usuário na navegação em seu site. O Asp.Net possui uma forma de gerenciar sua estrutura e fornece-la ao usuário.

Você pode gerenciar e documentar a estrutura do seu site usando um site map. O site map no Asp.Net é um arquivo Xml que contém a estrutura e a hierarquia do seu site, ele é utilizado para popular controles de navegação como NavigationMenu, SiteMapPath, e TreeView.

Para adicionar um site map clique com o botão direito no seu projeto e selecione Add New Item | Site Map. Será criado um arquivo xml com a extensão .sitemap. Você adiciona nós no site map adicionando elementos <siteMapNode>. Cada elemento desse possui o atributo title que será exibido ao usuário, atributo url que contém a página que irá navegar e o atributo description que contém uma definição da página. Exemplo de sitemap:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~/Default.aspx" title="Home" description="">
<siteMapNode url="~/Catalog.aspx" title="Our Catalog" description="">
<siteMapNode url="~/ProductCategory.aspx" title="Products" description="" />
<siteMapNode url="~/Product.aspx" title="View Product" description="" />
</siteMapNode>
<siteMapNode url="~/Cart.aspx" title="Shopping Cart" description="" />
<siteMapNode url="~/Account.aspx" title="My Account" description="">
<siteMapNode url="~/SignIn.aspx" title="Login" description="" />
<siteMapNode url="~/PassReset.aspx" title="Reset Password" description="" />
<siteMapNode url="~/AccountDetails.aspx" title="Manage Account" description="">
<siteMapNode url="~/Profile.aspx" title="Account Information" description="" />
<siteMapNode url="~/OrderHistory.aspx" title="My Orders" description="">
<siteMapNode url="~/ViewOrder.aspx" title="View Order" description="" />
</siteMapNode>
</siteMapNode>
</siteMapNode>
<siteMapNode url="~/AboutUs.aspx" title="About Us" description="" />
<siteMapNode url="~/Privacy.aspx" title="Privacy Policy" description="" />
<siteMapNode url="~/ContactUs.aspx" title="Contact Us" description="" />
<siteMapNode url="~/MediaKit.aspx" title="Media Relations" description="" />
</siteMapNode>
</siteMap>


Using the SiteMap Class

A classe SiteMap permite acessar em tempo de execução através do código de programação a hierarquia do seu site. Existem duas propriedades primárias RootNode e CurrentNode ambas retornam uma instância SiteMapNode. O objeto SiteMapNode representa um nó no seu arquivo sitemap e nele você tem acesso as propriedades antes listadas: title, url e description. Para ter acesso aos nós na hierarquia você deve utilizar as propriedades ParentNode, ChildNodes, NextSibling, e PreviousSibling na instância do SiteMapNode. O código abaixo mostra quem é o nível superior da página que esta sendo acessada:

protected void Button1_Click(object sender, EventArgs e)
{
  Response.Redirect(SiteMap.CurrentNode.ParentNode.Url);
}


Displaying Site Map Information to Users

O sitemap é apenas um arquivo xml com informações, para exibir esses dados ao usuário são necessários controles de navegação. Esses controles de navegação podem conectar diretamente em seu arquivo site map, vou conectar no controle SiteMapDataSource.

O SiteMapDataSource é um controle simples designado a permitir que o programador acesse o arquivo site map. Este controle é usado como fonte de dados de controles de navegação. Para usar este controle basta arrasta-lo para sua página e ele automaticamente irá conectar no site map definido no seu site.

Existem dois atributos que podem ser usados para configurar o controle SiteMapDataSource. ShowStartingNode você define como false caso não queira que o usuário visualize o nós raíz do seu site. O segundo é o StartingNodeOffset, é útil quando estiver usando um controle de sub-navegação e queira mostrar apenas partes da navegação. Veja como fica o código do controle:

<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" StartingNodeOffset="0" ShowStartingNode="False" />

Assim como o site map o controle SiteMapDataSource não tem representação visual para o usuário, é necessário utilizar algum controle de navegação que faça isso. Existem três principais controle de navegação no asp.net: Menu, TreeView, e SiteMapPath.

O controle Menu como o nome ja diz é para exibir a estrutura do seu site como um menu, o usuário conseguirá navegar desde as páginas raíz até seus últimos níveis. O Menu possui várias propriedade que envolvem principalmente layout e estilo. Mas existe dois atributos que o livro foca, é o DataSourceId e Orientation. No DataSourceId você irá definir o nome do controle DataSource, você pode informar o nome do SiteMapDataSource que adicionou em sua página. Já Orientation é para definir se irá mostrar o menu de forma veritical ou horizontal. Veja o código abaixo:

<asp:Menu ID="Menu1" runat="server" DataSourceID="SiteMapDataSource1" MaximumDynamicDisplayLevels="5" Orientation="Horizontal">
</asp:Menu>


Com base no site map que foi postado nesta lição, o resultado deste menu será:


Já o controle TreeView exibe a estrutura do site no formato de uma "árvore", onde o usuário poderá navegar entre os itens até chegar ao último nível e selecionar a página desejada, para utilizar o SiteMapDataSource como fonte de dados, deve ser feito o mesmo processo do controle Menu. Veja como fica a TreeView:


O último controle é o SiteMapPath, ele permite ao usuário saber em qual página ele esta, e quais são os níveis anteriores para chegar nesta página. Este controle cria um rastro de navegação até a página que o usuário esta utilizando. Adicionando este controle a sua página ele automaticamente irá utilizar o arquivo site map, não é necessário configurar seu DataSource como nos outros controles anteriores. Veja como fica seu resultado: