Team Foundation Server (TFS) – Visão Geral

Há algum tempo, os projetos eram desenvolvidos individualmente, porém, com o passar dos anos, surgiu à necessidade de compartilhar o código fonte entre pessoas que programavam a mesma aplicação, pois, mais pessoas passaram a fazer parte dos mesmos projetos.

Devido à necessidade citada acima, surgiram soluções de controle de código, tais como SVN, CVS, Visual Source Safe, dentre outras. Então foi criado o Team Foundation Server (TFS), que é um produto da Microsoft onde oferece controle de código, coleta de dados, relatórios e acompanhamento de projetos, sendo destinado para projetos de desenvolvimento de software colaborativo.

O TFS é totalmente baseado em WebServices, portanto, este permite que, pessoas de qualquer lugar trabalhem no mesmo projeto ao mesmo tempo.

Na versão 2010, a Microsoft lançou novos recursos que atendam também os desenvolvedores autônomos e pequenas empresas. Recursos que permitem o TFS ser instalado em sistemas operacionais como Windows Vista e Windows 7, sem a necessidade de ter um Windows Server instalado na máquina de desenvolvimento.

Portanto, utilizando o Team Foundation Server, gera-se mais agilidade e confiabilidade ao desenvolver um software e permite que a aplicação seja desenvolvida por uma equipe, estando essa, em qualquer lugar do mundo.

Como criar Url Amigável utilizando Global.asax

Atualmente é muito comum aplicações web, que exibem suas informações dinamicamente através do uso de scripts que rodam no servidor. Imagine uma página que exiba as informações completas de uma determinada notícia, a url seria algo como: http://www.site.com/noticias.aspx?id=3,onde 3 é o código identificador da notícia.
Isto é muito interessante, porém, normalmente encontram-se URLs grandes ou complicadas demais, difíceis de memorizar e sem significado, onde até mesmo, dificulta a indexação do site por mecanismos de busca.
O ASP.NET 2.0 traz recursos de URL rewriting, onde permitem criar URLs amigáveis, por exemplo, pode-se permitir que o usuário acesse a notícia 3, citada no exemplo acima, da seguinte maneira : http://www.site.com/noticia,3,titulo-da-noticia ..
O exemplo mostrado neste artigo é de simples entendimento, será criada uma simples aplicação onde possua uma página que contenha uma listagem de notícias, sendo que, quando o usuário clicar no link da notícia que deseja ler, este será redirecionado a uma página de visualização, onde mostrará o identificador desta notícia.
Utilizando o Visual Studio 2008, crie uma página chamada Default.aspx, adicione 3 HyperLinks, identificados como: hlNoticia1, hlNoticia2 e hlNoticia 3. Defina a propriedade Text da seguinte maneira: "Título da primeira notícia", "Título da segunda notícia" e "Título da terceira notícia", respectivamente. Posicione os componentes em tela, observe na Figura 1.
Figura 1 – HyperLinks posicionados
Figura 1 – HyperLinks posicionados
Em seguida, será adicionado os links para cada "notícia", imagine que, quando forem clicados, deve-se transferir através de QueryString o ID para a página Noticia.aspx, para que a notícia visualizada por completo, ou no nosso caso, exibir o identificador na página.
Adicione o link do primeiro HyperLink da seguinte maneira : "noticias.aspx?id=1". Agora imagine uma URL, que atinja este objetivo, como exemplo, pode-se criá-la da seguinte forma: "noticia,1,titulo-da-primeira-noticia.aspx". Perceba que, neste endereço de URL, foi adicionado o "id" de valor "1" e o título da notícia, tornando assim, um endereço mais simples de se trabalhar.
Adicione os seguintes links para os componentes:
hlNoticia1 - noticia,1,titulo-da-primeira-noticia.aspx
hlNoticia2 - noticia,2,titulo-da-segunda-noticia.aspx
hlNoticia3 - noticia,3,titulo-da-terceira-noticia.aspx
Agora, compile a aplicação, perceba que, ao clicar no link, será gerado o seguinte erro "The resource cannot be found.", pois o servidor não encontrou a página informada. Isso acontece por que o diretório informado não existe, então, para que este diretório seja funcional, deve-se criar a página Noticias.aspx, pois esta irá exibir toda a notícia detalhada.
Após criar esta nova página da web, deve-se configurar a aplicação para que, ao clicar no hlNoticia1, seja direcionado ao endereço "noticia,1,titulo-da-primeira-noticia.aspx", e a aplicação interprete este diretório da seguinte maneira: "Noticias.aspx?id=1".
Para exemplificar a visualização, no Page_Load da página Noticias.aspx, adicione o seguinte código:
string id = Request.QueryString["id"];
Response.Write("Identificador da notícia: " + id);
Para que a aplicação interprete a url amigável e entenda que é a página Noticias.aspx, deve-se adicionar um Global.asax, como mostra a Figura 2.
Figura 2 – Add new Global.asax
Figura02 – Add new Global.asax
Através do Global.asax, pode-se executar um determinado código quando a aplicação é iniciada/finalizada ou até mesmo quando qualquer página da aplicação for requisitada,
No Global.asax, adicione o seguinte método abaixo:

protected void Application_BeginRequest(Object sender, EventArgs e)
{
    HttpContext incoming = HttpContext.Current;
    string oldpath = incoming.Request.Path.ToLower();
    string pageid;
    Regex regex = new Regex(@"noticia,(\S+),(\S+).aspx", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
    MatchCollection matches = regex.Matches(oldpath);
    if(matches.Count > 0)
    {
        //Extrai o id da noticia e envia para Noticias.aspx
        pageid = matches[0].Groups[1].ToString();
incoming.RewritePath(string.Format("Noticias.aspx?id={0}&titulo={0}", pageid));
    }
}
Deve-se entender que, o método Application_BeginRequest é disparado cada vez que uma nova requisição é efetuada, portanto antes de a página ser carregada, este método será executado.
Entendendo o código:
Perceba que, inicialmente foi instanciado a variável icoming, recebendo o contexto da aplicação, em seguida duas strings foram criadas, oldpath e pageid, sendo que uma irá receber o caminho absoluto da url, e a outra receberá o id passado na URL, respectivamente.
Foi usado o Regex com o código (@"noticia,(\S+),(\S+).aspx que é uma expressão regular. Observe que, essa expressão regular recebe a url passada, sendo que, o primeiro parâmetro contém o valor do ID da notícia e o segundo possui o título.
Veja que, incoming.RewritePath irá redirecionar a url amigável para a página correta, passando o id e o título da mesma.
Execute o projeto e perceba que, quando clicar sobre qualquer hyperlink q está na Default.aspx, será redirecionado para a pagina Noticias.aspx de uma forma amigável, observe a Figura 3.
Figura 3 – Página com Url Amigável
Figura 3 – Página com Url Amigável
O intuito deste artigo foi apresentar como criar URLs amigáveis, tanto para o usuário quanto para os mecanismos de busca. Escreva soluções que concretizem sua necessidade, utilize a criatividade e atinja seus objetivos de forma eficaz.

CascadingDropDown Passo a Passo

Este artigo tem como objetivo criar um passo a passo, informando o que é, e como funciona o CascadingDropDown.
Deve-se entender que, o CascadingDropDown é um webControl que faz parte do Atlas toolkit, onde permite a montagem de DropDowns em cascata, ou seja, o usuário seleciona uma informação na primeira dropDown para filtrar a 2a e assim por diante, em um número indeterminado de vezes.
Para entender melhor, será mostrado um exemplo onde se realiza uma busca de um veículo, através do fabricante, modelo, ano e versão. Para isso, essas informações devem estar disponíveis em dropDowns, para que o usuário realize a filtragem, veja na Figura 1.

Figura 1- Busca de veículo
Antes de partir para o desenvolvimento da aplicação, primeiramente será criado o banco, para que assim, interaja-se posteriormente o mesmo com os dropDowns.
Criando o banco

Foi utilizado o banco SQL Server 2005 para criação da base “Mercado” e das tabelas “tbFabricante”, “tbModelo”, “tbAno” e “tbVersao”.
Segue abaixo o script de criação:

/*Cria Base Mercado */

create database Mercado


/*Cria tabela tbFabricante */

CREATE TABLE [dbo].[tbFabricante](
      [IdFabricante] [int] IDENTITY(1,1) NOT NULL,
      [Nome] [nvarchar](50),
 CONSTRAINT [PK_tb_Fabricante] PRIMARY KEY CLUSTERED
(
      [IdFabricante] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

/*Cria tabela tbModelo que possui uma referência do fabricante */

CREATE TABLE [dbo].[tbModelo](
      [IdModelo] [int] IDENTITY(1,1) NOT NULL,
      [Nome] [nvarchar](50) ,
      [IdFabricante] [int] NOT NULL,
 CONSTRAINT [PK_tbModelo] PRIMARY KEY CLUSTERED
(
      [IdModelo] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[tbModelo]  WITH CHECK ADD  CONSTRAINT [FK_Modelo_Fabricante] FOREIGN KEY([IdFabricante])
REFERENCES [dbo].[tbFabricante] ([IdFabricante])
GO
ALTER TABLE [dbo].[tbModelo] CHECK CONSTRAINT [FK_Modelo_Fabricante]



/*Cria tabela tbAno que possui uma referÊncia do modelo */

CREATE TABLE [dbo].[tbAno](
      [IdAno] [int] IDENTITY(1,1) NOT NULL,
      [Nome] [nvarchar](50) ,
      [IdModelo] [int] NOT NULL,
 CONSTRAINT [PK_tbAno] PRIMARY KEY CLUSTERED
(
      [IdAno] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[tbAno]  WITH CHECK ADD  CONSTRAINT [FK_Ano_Modelo] FOREIGN KEY([IdModelo])
REFERENCES [dbo].[tbModelo] ([IdModelo])
GO
ALTER TABLE [dbo].[tbAno] CHECK CONSTRAINT [FK_Ano_Modelo]



/*Cria tabela tbVersao que possui uma referência do ano */

CREATE TABLE [dbo].[tbVersao](
      [IdVersao] [int] IDENTITY(1,1) NOT NULL,
      [Nome] [nvarchar](50) ,
      [IdAno] [int] NOT NULL,
 CONSTRAINT [PK_tbVersao] PRIMARY KEY CLUSTERED
(
      [IdVersao] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[tbVersao]  WITH CHECK ADD  CONSTRAINT [FK_Versao_Ano] FOREIGN KEY([IdAno])
REFERENCES [dbo].[tbAno] ([IdAno])
GO
ALTER TABLE [dbo].[tbVersao] CHECK CONSTRAINT [FK_Versao_Ano]
Observa-se na Figura 2 que a tabela criada possui o seguinte relacionamento:

Figura 2 – Diagrama da base Mercado
Agora, serão inseridos alguns registros no banco recém criado, com objetivo futuro de testes. Segue script abaixo:
/*Inserir na tbFabricante*/

INSERT [tbFabricante] ([Nome]) VALUES ('FIAT')
INSERT [tbFabricante] ([Nome]) VALUES ('FORD')


/*Inserir na tbModelo com referencia ao fabricante*/

INSERT [tbModelo] ([Nome], [IdFabricante]) VALUES ('PALIO', 1)
INSERT [tbModelo] ([Nome], [IdFabricante]) VALUES ('UNO', 1)
INSERT [tbModelo] ([Nome], [IdFabricante]) VALUES ('FIESTA', 2)


/*Inserir na tbAno com referência ao modelo */


INSERT [tbAno] ([Nome], [IdModelo]) VALUES ('2011', 1)
INSERT [tbAno] ([Nome], [IdModelo]) VALUES ('2010', 1)
INSERT [tbAno] ([Nome], [IdModelo]) VALUES ('2010', 2)
INSERT [tbAno] ([Nome], [IdModelo]) VALUES ('2009', 2)
INSERT [tbAno] ([Nome], [IdModelo]) VALUES ('2008', 3)
INSERT [tbAno] ([Nome], [IdModelo]) VALUES ('2009', 3)


/*Inserir na tbVersao com referência ao ano*/


INSERT [tbVersao] ([Nome], [IdAno]) VALUES ('1.8 MPI WEEKEND 8V', 1)
INSERT [tbVersao] ([Nome], [IdAno]) VALUES ('1.0 MPI ELX 8V', 1)
INSERT [tbVersao] ([Nome], [IdAno]) VALUES ('1.8 MPI R 8V', 3)
INSERT [tbVersao] ([Nome], [IdAno]) VALUES ('1.4 MPI TREKKING', 3)
INSERT [tbVersao] ([Nome], [IdAno]) VALUES ('1.6 MPI TRAIL', 8)
Após a criação do banco, incia-se o desenvolvimento da aplicação. Utilizando o Visual Studio 2008, crie um novo projeto denominado Mercado, em seguida adicione quatro DropDownList e quatro Label no formulário do projeto (Figura 3), renomeie-os  para “ddlFabricante”, “ddlModelo”, “ddlAno”, “ddlVersao”, conseqüentemente. Posicione-os em tela para ficar esteticamente viável (observe a Figura 4). Compile o projeto e confirme a opção Add a new Web.config.

Figura 3 – Toolbox do Visual Studio 2005

Figura 4 – Página em construção
É claro que, como a aplicação está utilizando uma extensão do Ajax, deve-se ter na nossa aplicação, mais especificamente na pasta Bin, as ddls do AjaxControlToolKit, caso você não possua, clique aqui (http://ajaxcontroltoolkit.codeplex.com/releases/view/43475) para baixar.
Agora, deve-se entender o seguinte, é claro que, pode-se popular estes dropDowns sem utilizar o CascadingDropDown, porém o foco deste artigo é ver as vantagens que este webControl proporciona.
Toda a lógica sobre como preencher os DropDownList através de buscas no banco, ficará armazenada em um WebService. O WebService de exemplo usado neste exemplo, lê os dados a partir de uma ‘select’ SQL simples e exibe-os nos combos em questão.
Deve-se então, criar este WebService, para isso, vá até a Solution Explorer do Visual Studio, em seguida clique com o botão direito sobre o diretório do projeto, escolha Add New Item (Figura 5). Nesta nova janela, selecione o item Web Service e renomeie-o para wsVeiculo.asmx, em seguida clique em Add ( veja na Figura 6).
Deve-se observar que, para trabalhar com CascadingDropDown, o WebService precisa estar localizado no mesmo site que a página criada, devido a segurança contra Cross-Site Scripting existente no browser, que impedirá um script de fazer a chamada para um webService em outro domínio.

Figura 5 – Add New Item

Figura 6 – Add novo Web Service
Após adicionar o WebService no projeto, vá ao Solution Explorer, em seguida acesse App_Code -> wsVeiculo.cs. Nesta classe serão configurados os métodos que irão realizar as consultas que forem necessárias à base de dados.
Dentro do wsVeiculo.cs, apague o método HelloWorld, pois este é apenas demonstrativo.em seguida, deve-se adicionar a seguinte linha antes de publicicar a classe, pois esta, tem o objetivo de indicar que o WebService poderá ser invocado a partir de um script.
[ScriptService]
Póximo passo é instanciar uma string onde indicará qual conexão de banco de dados será utilizada, porém, para isso, deve-se informar para aplicação, qual servidor deseja acessar, bem como a base de dados desejada, portanto, acesse o web.config que foi criado, e configure sua connectionstring da seguinte maneira.
<connectionStrings>
   <add name="mercadoCS" connectionString="Data Source=NOMEDOCOMPUTADOR\SQLEXPRESS;Initial Catalog=NOMEDABASE(Mercado);Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
Agora volte ao WebService, e instancie uma string, com o nome conString, que irá através do ConfigurationManager, receber a string de conexão informada no web.config.
string conString = ConfigurationManager.ConnectionStrings["mercadoCS"].ToString();
Importe a classe Configuration:
using System.Configuration;
Próximo passo será criar o método que será utilizado para retornar os fabricantes para o DropDownList ddlFabricante.
    [WebMethod]
    public AjaxControlToolkit.CascadingDropDownNameValue[] GetDropDownFabricante(string knownCategoryValues, string category)
    {
        SqlConnection sqlConn = new SqlConnection(conString);
        sqlConn.Open();
        SqlCommand sqlSelect = new SqlCommand("select * from tbFabricante ORDER BY Nome", sqlConn);
        sqlSelect.CommandType = System.Data.CommandType.Text;
        SqlDataAdapter sqlAdapter = new SqlDataAdapter(sqlSelect);
        DataSet myDataset = new DataSet();
        sqlAdapter.Fill(myDataset);
        sqlConn.Close();

        List<AjaxControlToolkit.CascadingDropDownNameValue> cascadingValues = new List<AjaxControlToolkit.CascadingDropDownNameValue>();

        foreach (DataRow dRow in myDataset.Tables[0].Rows)
        {
            string categoryID = dRow["IdFabricante"].ToString();
            string categoryName = dRow["Nome"].ToString();
            cascadingValues.Add(new AjaxControlToolkit.CascadingDropDownNameValue(categoryName, categoryID));
        }

        return cascadingValues.ToArray();
    }
Este WebService criado, recebe 2 parâmetros string e retorna um parâmetro de tipo especial. É valido frisar que, AtlasControlToolkit.CascadingDropDownNameValue, é um array deste tipo . O parâmetro Category contém a informação que está sendo requisitada. Cada combo recebe um nome, uma identificação para a informação que ela representa. Pode-se utilizar somente este método para retornar para todos droDowns que for desejado, porém, será apresentado com métodos independentes para melhor entendimento.
Para verificar se este método está funcionando corretamente em conjunto à aplicação, basta voltar para pagina Default.aspx. Trabalhando em modo Source, adicione o código abaixo antes de começar a tag HTML, pois este irá “informar” para o AjaxControlToolKit que esta página irá utilizá-lo.
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
Em seguida será adicionado o ScriptManager na página, pois este é necessário quando se trabalha com Ajax, observe na Figura 7.

Figura 7 – Add ScriptManager
Neste momento, será configurado o webControl cascadingdropdown, adicione o seguinte código na aplicação:
<cc1:CascadingDropDown ID="cddFabricante" runat="server" Category="IdFabricante" TargetControlID="ddlFabricante" PromptText="Selecione um Fabricante" LoadingText="carregando fabricantes…" ServicePath="wsVeiculo.asmx"                ServiceMethod="GetDropDownFabricante"></cc1:CascadingDropDown>
Deve-se entender que, o CascadingDropDown aparece como um webControl não visual e atua como um extender. Renomei o ID para cddFabricante, veja abaixo suas propriedades:
·         Category - Nome da categoria representada pela DropdDownList. Em nosso exemplo, "Id" pois este é o nosso identificador (da tabela tbFabricante);
·         TargetControlID - Nome da DropDownList a ser identificada. Definimos o ddlFabricante;
·         PromptText - Texto de um item nulo que é inserido na DropDownList, por exemplo, "Selecione um Fabricante";
·         LoadingText  - O texto que será exibido no momento em que os dados estão sendo carregados;
·         ServicePath - O diretório de onde está localizado seu WebService.asmx;
·         ServiceMethod - Nome do método no WebService que será executado.
Após configurar o CascadingDropDown, compile e veja se o ddlFabricante exibiu os fabricantes cadastrados, repare na Figura 8.

Figura 8 – Seleção de um Fabricante
Sendo exibido corretamente todos fabricantes, agora será criado o WebService do Modelo, Ano e Verão, segue abaixo, o código exemplo do método do Modelo:
    [WebMethod]
    public AjaxControlToolkit.CascadingDropDownNameValue[] GetDropDownModelo(string knownCategoryValues, string category)
    {
        int categoryID;

        StringDictionary categoryValues = AjaxControlToolkit.CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);

        categoryID = Convert.ToInt32(categoryValues["IdFabricante"]);


        SqlConnection sqlConn = new SqlConnection(conString);
        sqlConn.Open();
        SqlCommand sqlSelect = new SqlCommand("select * from tbModelo WHERE IdFabricante = @IdFabricante order by Nome", sqlConn);
        sqlSelect.CommandType = System.Data.CommandType.Text;
        sqlSelect.Parameters.Add("IdFabricante", SqlDbType.Int).Value = categoryID;
        SqlDataAdapter sqlAdapter = new SqlDataAdapter(sqlSelect);
        DataSet myDataset = new DataSet();
        sqlAdapter.Fill(myDataset);
        sqlConn.Close();

        List<AjaxControlToolkit.CascadingDropDownNameValue> cascadingValues = new List<AjaxControlToolkit.CascadingDropDownNameValue>();

        foreach (DataRow dRow in myDataset.Tables[0].Rows)
        {
            string productID = dRow["IdModelo"].ToString();
            string productName = dRow["Nome"].ToString();
            cascadingValues.Add(new AjaxControlToolkit.CascadingDropDownNameValue(productName, productID));
        }

        return cascadingValues.ToArray();
    }
Observando este método, percebem-se poucas diferenças para o GetDropDownFabricante, veja o código abaixo :
    categoryID = Convert.ToInt32(categoryValues["IdFabricante"]);
O categoryID vai receber o valor identificador do DropDownList (no nosso caso ddlFabricante), percebam que, em categoryValues["IdFabricante"], o identificador entre as aspas é exatamente o mesmo que está na tabela tbFabricante.
Será feita uma busca na tabela do modelo de acordo com o fabricante que foi selecionado, observe :
    sqlSelect.Parameters.Add("IdFabricante", SqlDbType.Int).Value = categoryID;
Deve-se entender que , o retorno productId, neste método, é o identificador do modelo, vejam:
    string productID = dRow["IdModelo"].ToString();
Segue abaixo os metodos do Ano e Versão, respectivamente:

    [WebMethod]
    public AjaxControlToolkit.CascadingDropDownNameValue[] GetDropDownAno(string knownCategoryValues, string category)
    {
        int categoryID;

        StringDictionary categoryValues = AjaxControlToolkit.CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);

        categoryID = Convert.ToInt32(categoryValues["IdModelo"]);


        SqlConnection sqlConn = new SqlConnection(conString);
        sqlConn.Open();
        SqlCommand sqlSelect = new SqlCommand("select * from tbAno WHERE IdModelo = @IdModelo order by Nome Desc", sqlConn);
        sqlSelect.CommandType = System.Data.CommandType.Text;
        sqlSelect.Parameters.Add("IdModelo", SqlDbType.Int).Value = categoryID;
        SqlDataAdapter sqlAdapter = new SqlDataAdapter(sqlSelect);
        DataSet myDataset = new DataSet();
        sqlAdapter.Fill(myDataset);
        sqlConn.Close();

        List<AjaxControlToolkit.CascadingDropDownNameValue> cascadingValues = new List<AjaxControlToolkit.CascadingDropDownNameValue>();

        foreach (DataRow dRow in myDataset.Tables[0].Rows)
        {
            string productID = dRow["IdAno"].ToString();
            string productName = dRow["Nome"].ToString();
            cascadingValues.Add(new AjaxControlToolkit.CascadingDropDownNameValue(productName, productID));
        }

        return cascadingValues.ToArray();
    }



    [WebMethod]
    public AjaxControlToolkit.CascadingDropDownNameValue[] GetDropDownVersao(string knownCategoryValues, string category)
    {
        int categoryID;

        StringDictionary categoryValues = AjaxControlToolkit.CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);

        categoryID = Convert.ToInt32(categoryValues["IdAno"]);


        SqlConnection sqlConn = new SqlConnection(conString);
        sqlConn.Open();
        SqlCommand sqlSelect = new SqlCommand("select * from tbVersao WHERE IdAno = @IdAno order by Nome", sqlConn);
        sqlSelect.CommandType = System.Data.CommandType.Text;
        sqlSelect.Parameters.Add("IdAno", SqlDbType.Int).Value = categoryID;
        SqlDataAdapter sqlAdapter = new SqlDataAdapter(sqlSelect);
        DataSet myDataset = new DataSet();
        sqlAdapter.Fill(myDataset);
        sqlConn.Close();

        List<AjaxControlToolkit.CascadingDropDownNameValue> cascadingValues = new List<AjaxControlToolkit.CascadingDropDownNameValue>();

        foreach (DataRow dRow in myDataset.Tables[0].Rows)
        {
            string productID = dRow["IdVersao"].ToString();
            string productName = dRow["Nome"].ToString();
            cascadingValues.Add(new AjaxControlToolkit.CascadingDropDownNameValue(productName, productID));
        }

        return cascadingValues.ToArray();
    }
Agora que foram criados os métodos, será ativado os CascadingDropDown para o drops ddlModelo, ddlAno e ddlVersao.
Observe que, a única propriedade diferente neste cddModelo, é a ParentControlID, que refere ao DropDownList “pai”, neste caso é o ddlFabricante.
Modelo :
            <cc1:CascadingDropDown ID="cddModelo" runat="server" Category="IdModelo" TargetControlID="ddlModelo" PromptText="Selecione um Modelo" ParentControlID="ddlFabricante" LoadingText="carregando modelos…" ServicePath="wsVeiculo.asmx" ServiceMethod="GetDropDownModelo">
            </cc1:CascadingDropDown>
Ano:
            <cc1:CascadingDropDown ID="cddAno" runat="server" Category="IdAno" TargetControlID="ddlAno" PromptText="Selecione um Ano" ParentControlID="ddlModelo" LoadingText="carregando anos…" ServicePath="wsVeiculo.asmx" ServiceMethod="GetDropDownAno">
            </cc1:CascadingDropDown>
Versão:
            <cc1:CascadingDropDown ID="cddVersao" runat="server" Category="IdVersao"   TargetControlID="ddlVersao" PromptText="Selecione um Versão" ParentControlID="ddlAno" LoadingText="carregando versões…" ServicePath="wsVeiculo.asmx" ServiceMethod="GetDropDownVersao">      
            </cc1:CascadingDropDown>
Como o estudo realizado, percebe-se que, utilizando o CascadingDropDown para realizar este tipo de filtragem, facilita a implementação do código, e gera agilidade no carregamento de informações, devido essas consultas serem feitas através de WebServices.