Uma visão geral de inserção, atualização e exclusão de dados (C#)

por Scott Mitchell

Baixar o aplicativo de exemplo ou baixar PDF

Neste tutorial, veremos como mapear os métodos Insert (), Update () e Delete () de ObjectDataSource para os métodos de classes de BLL, bem como para configurar os controles GridView, DetailsView e FormView para fornecer recursos de modificação de dados.

Introdução

Nos últimos vários tutoriais examinamos como exibir dados em uma página ASP.NET usando os controles GridView, DetailsView e FormView. Esses controles simplesmente funcionam com os dados fornecidos a eles. Normalmente, esses controles acessam dados por meio do uso de um controle da fonte de dados, como o ObjectDataSource. Vimos como o ObjectDataSource atua como um proxy entre a página ASP.NET e os dados subjacentes. Quando um GridView precisa exibir dados, ele invoca o método de Select() de ObjectDataSource que, por sua vez, invoca um método de nossa camada de lógica de negócios (BLL), que chama um método no TableAdapter (DAL) apropriado da camada de acesso a dados que, por sua vez, envia uma consulta de SELECT para o Northwind.

Lembre-se de que quando criamos os TableAdapters na DAL em nosso primeiro tutorial, o Visual Studio adicionou automaticamente os métodos para inserção, atualização e exclusão de dados da tabela de banco de dado subjacente. Além disso, ao criar uma camada de lógica de negócios , criamos métodos na BLL que se chamaram para esses métodos da Dal de modificação de dados.

Além de seu método Select(), o ObjectDataSource também tem os métodos Insert(), Update()e Delete(). Como o método Select(), esses três métodos podem ser mapeados para métodos em um objeto subjacente. Quando configurado para inserir, atualizar ou excluir dados, os controles GridView, DetailsView e FormView fornecem uma interface do usuário para modificar os dados subjacentes. Essa interface do usuário chama os métodos Insert(), Update()e Delete() do ObjectDataSource, que invocam os métodos associados do objeto subjacente (consulte a Figura 1).

os métodos Insert (), Update () e Delete () do ObjectDataSource servem como um proxy para a BLL

Figura 1: os métodos Insert(), Update()e Delete() do ObjectDataSource servem como um proxy para a BLL (clique para exibir a imagem em tamanho normal)

Neste tutorial, veremos como mapear os métodos Insert(), Update()e Delete() do ObjectDataSource para métodos de classes na BLL, bem como configurar os controles GridView, DetailsView e FormView para fornecer recursos de modificação de dados.

Etapa 1: criando as páginas da Web de tutoriais de inserção, atualização e exclusão

Antes de começarmos a explorar como inserir, atualizar e excluir dados, primeiro vamos reservar um momento para criar as páginas ASP.NET em nosso projeto de site, que precisaremos para este tutorial e para as próximas várias delas. Comece adicionando uma nova pasta chamada EditInsertDelete. Em seguida, adicione as seguintes páginas ASP.NET a essa pasta, assegurando a associação de cada página com a página mestra Site.master:

  • Default.aspx
  • Basics.aspx
  • DataModificationEvents.aspx
  • ErrorHandling.aspx
  • UIValidation.aspx
  • CustomizedUI.aspx
  • OptimisticConcurrency.aspx
  • ConfirmationOnDelete.aspx
  • UserLevelAccess.aspx

Adicionar as páginas ASP.NET para os tutoriais relacionados à modificação de dados

Figura 2: adicionar as páginas ASP.net para os tutoriais relacionados à modificação de dados

Assim como nas outras pastas, Default.aspx na pasta EditInsertDelete listará os tutoriais em sua seção. Lembre-se de que o controle de usuário SectionLevelTutorialListing.ascx fornece essa funcionalidade. Portanto, adicione esse controle de usuário a Default.aspx arrastando-o da Gerenciador de Soluções para a modo de exibição de Design da página.

adicionar o controle de usuário SectionLevelTutorialListing. ascx a default. aspx

Figura 3: Adicionar o controle de usuário SectionLevelTutorialListing.ascx ao Default.aspx (clique para exibir a imagem em tamanho normal)

Por fim, adicione as páginas como entradas ao arquivo de Web.sitemap. Especificamente, adicione a seguinte marcação após a formatação personalizada <siteMapNode>:

<siteMapNode title="Editing, Inserting, and Deleting"
    url="~/EditInsertDelete/Default.aspx"
    description="Samples of Reports that Provide Editing, Inserting,
                  and Deleting Capabilities">
    <siteMapNode url="~/EditInsertDelete/Basics.aspx"
        title="Basics"
        description="Examines the basics of data modification with the
                      GridView, DetailsView, and FormView controls." />
    <siteMapNode url="~/EditInsertDelete/DataModificationEvents.aspx"
        title="Data Modification Events"
        description="Explores the events raised by the ObjectDataSource
                      pertinent to data modification." />
    <siteMapNode url="~/EditInsertDelete/ErrorHandling.aspx"
        title="Error Handling"
        description="Learn how to gracefully handle exceptions raised
                      during the data modification workflow." />
    <siteMapNode url="~/EditInsertDelete/UIValidation.aspx"
        title="Adding Data Entry Validation"
        description="Help prevent data entry errors by providing validation." />
    <siteMapNode url="~/EditInsertDelete/CustomizedUI.aspx"
        title="Customize the User Interface"
        description="Customize the editing and inserting user interfaces." />
    <siteMapNode url="~/EditInsertDelete/OptimisticConcurrency.aspx"
        title="Optimistic Concurrency"
        description="Learn how to help prevent simultaneous users from
                      overwritting one another s changes." />
    <siteMapNode url="~/EditInsertDelete/ConfirmationOnDelete.aspx"
        title="Confirm On Delete"
        description="Prompt a user for confirmation when deleting a record." />
    <siteMapNode url="~/EditInsertDelete/UserLevelAccess.aspx"
        title="Limit Capabilities Based on User"
        description="Learn how to limit the data modification functionality
                      based on the user role or permissions." />
</siteMapNode>

Depois de atualizar Web.sitemap, Reserve um momento para exibir o site de tutoriais por meio de um navegador. O menu à esquerda agora inclui itens para os tutoriais de edição, inserção e exclusão.

O mapa do site agora inclui entradas para os tutoriais de edição, inserção e exclusão

Figura 4: o mapa do site agora inclui entradas para os tutoriais de edição, inserção e exclusão

Etapa 2: adicionando e Configurando o controle ObjectDataSource

Como GridView, DetailsView e FormView diferem em seus recursos e layout de modificação de dados, vamos examinar cada um deles individualmente. No entanto, em vez de ter cada controle usando seu próprio ObjectDataSource, vamos criar apenas um ObjectDataSource que todos os exemplos de controle possam compartilhar.

Abra a página Basics.aspx, arraste um ObjectDataSource da caixa de ferramentas para o designer e clique no link configurar fonte de dados de sua marca inteligente. Como a ProductsBLL é a única classe BLL que fornece os métodos de edição, inserção e exclusão, configure o ObjectDataSource para usar essa classe.

configurar o ObjectDataSource para usar a classe ProductsBLL

Figura 5: configurar o ObjectDataSource para usar a classe ProductsBLL (clique para exibir a imagem em tamanho normal)

Na próxima tela, podemos especificar quais métodos da classe ProductsBLL são mapeados para o Select()do ObjectDataSource, Insert(), Update()e Delete() selecionando a guia apropriada e escolhendo o método na lista suspensa. A Figura 6, que deve parecer familiar agora, mapeia o método Select() do ObjectDataSource para o método GetProducts() da classe ProductsBLL. Os métodos Insert(), Update()e Delete() podem ser configurados selecionando a guia apropriada na lista ao longo da parte superior.

fazer com que o ObjectDataSource retorne todos os produtos

Figura 6: fazer com que o ObjectDataSource retorne todos os produtos (clique para exibir a imagem em tamanho normal)

As figuras 7, 8 e 9 mostram as guias UPDATE, INSERT e DELETE do ObjectDataSource. Configure essas guias para que os métodos Insert(), Update()e Delete() invoquem os métodos UpdateProduct, AddProducte DeleteProduct da classe ProductsBLL, respectivamente.

mapear o método Update () do ObjectDataSource para o método UpdateProduct da classe ProductBLL

Figura 7: mapear o método de Update() do ObjectDataSource para o método de UpdateProduct da classe ProductBLL (clique para exibir a imagem em tamanho normal)

mapear o método Insert () do ObjectDataSource para o método addproduct da classe ProductBLL

Figura 8: mapear o método de Insert() do ObjectDataSource para o método Add Product da classe ProductBLL (clique para exibir a imagem em tamanho normal)

mapear o método Delete () do ObjectDataSource para o método DeleteProduct da classe ProductBLL

Figura 9: mapear o método de Delete() do ObjectDataSource para o método de DeleteProduct da classe ProductBLL (clique para exibir a imagem em tamanho normal)

Talvez você tenha notado que as listas suspensas nas guias atualizar, inserir e excluir já tinham esses métodos selecionados. Isso é obrigado ao nosso uso do DataObjectMethodAttribute que decora os métodos de ProductsBLL. Por exemplo, o método DeleteProduct tem a seguinte assinatura:

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Delete, true)]
public bool DeleteProduct(int productID)
{
    ...
}

O atributo DataObjectMethodAttribute indica a finalidade de cada método, seja para seleção, inserção, atualização ou exclusão, e se é o valor padrão. Se você omitir esses atributos ao criar suas classes de BLL, precisará selecionar manualmente os métodos nas guias atualizar, inserir e excluir.

Depois de garantir que os métodos de ProductsBLL apropriados sejam mapeados para os métodos Insert(), Update()e Delete() do ObjectDataSource, clique em concluir para concluir o assistente.

Examinando a marcação do ObjectDataSource

Depois de configurar o ObjectDataSource por meio de seu assistente, vá para a exibição de código-fonte para examinar a marcação declarativa gerada. A marca <asp:ObjectDataSource> especifica o objeto subjacente e os métodos a serem invocados. Além disso, há DeleteParameters, UpdateParameterse InsertParameters que mapeiam para os parâmetros de entrada dos métodos AddProduct, UpdateProducte DeleteProduct da classe ProductsBLL:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    DeleteMethod="DeleteProduct" InsertMethod="AddProduct"
    OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
    TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
    <DeleteParameters>
        <asp:Parameter Name="productID" Type="Int32" />
    </DeleteParameters>
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
        <asp:Parameter Name="categoryID" Type="Int32" />
        <asp:Parameter Name="quantityPerUnit" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="unitsInStock" Type="Int16" />
        <asp:Parameter Name="unitsOnOrder" Type="Int16" />
        <asp:Parameter Name="reorderLevel" Type="Int16" />
        <asp:Parameter Name="discontinued" Type="Boolean" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
    <InsertParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
        <asp:Parameter Name="categoryID" Type="Int32" />
        <asp:Parameter Name="quantityPerUnit" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="unitsInStock" Type="Int16" />
        <asp:Parameter Name="unitsOnOrder" Type="Int16" />
        <asp:Parameter Name="reorderLevel" Type="Int16" />
        <asp:Parameter Name="discontinued" Type="Boolean" />
    </InsertParameters>
</asp:ObjectDataSource>

O ObjectDataSource inclui um parâmetro para cada um dos parâmetros de entrada para seus métodos associados, assim como uma lista de SelectParameter s está presente quando o ObjectDataSource está configurado para chamar um método Select que espera um parâmetro de entrada (como GetProductsByCategoryID(categoryID)). Como veremos em breve, os valores para esses DeleteParameters, UpdateParameterse InsertParameters são definidos automaticamente pelo GridView, DetailsView e FormView antes de invocar o método Insert(), Update()ou Delete() do ObjectDataSource. Esses valores também podem ser definidos programaticamente conforme necessário, como discutiremos em um tutorial futuro.

Um efeito colateral de usar o assistente para configurar o para ObjectDataSource é que o Visual Studio define a propriedade OldValuesParameterFormatString como original_{0}. Esse valor de propriedade é usado para incluir os valores originais dos dados que estão sendo editados e é útil em dois cenários:

  • Se, ao editar um registro, os usuários forem capazes de alterar o valor da chave primária. Nesse caso, o novo valor de chave primária e o valor da chave primária original devem ser fornecidos para que o registro com o valor da chave primária original possa ser encontrado e ter seu valor atualizado de acordo.
  • Ao usar a simultaneidade otimista. A simultaneidade otimista é uma técnica para garantir que dois usuários simultâneos não substituam as alterações de outra, e é o tópico para um tutorial futuro.

A propriedade OldValuesParameterFormatString indica o nome dos parâmetros de entrada nos métodos Update e Delete do objeto subjacente para os valores originais. Discutiremos essa propriedade e sua finalidade mais detalhadamente quando explorarmos a simultaneidade otimista. No entanto, faço isso agora porque nossos métodos de BLL não esperam os valores originais e, portanto, é importante que removamos essa propriedade. Deixar a propriedade OldValuesParameterFormatString definida como qualquer coisa diferente do padrão ({0}) causará um erro quando um controle da Web de dados tentar invocar os métodos Update() ou Delete() de ObjectDataSource, pois o ObjectDataSource tentará passar o UpdateParameters ou DeleteParameters especificado, bem como os parâmetros de valor original.

Se isso não for extremamente claro neste momento, não se preocupe, vamos examinar essa propriedade e seu utilitário em um tutorial futuro. Por enquanto, apenas tenha certeza de remover essa declaração de propriedade por completo da sintaxe declarativa ou definir o valor para o valor padrão ({0}).

Note

Se você simplesmente desmarcar o valor da propriedade OldValuesParameterFormatString da janela Propriedades no modo de exibição de Design, a propriedade ainda existirá na sintaxe declarativa, mas será definida como uma cadeia de caracteres vazia. Isso, infelizmente, ainda resultará no mesmo problema discutido acima. Portanto, remova a propriedade completamente da sintaxe declarativa ou, na janela Propriedades, defina o valor como o padrão, {0}.

Etapa 3: adicionando um controle da Web de dados e Configurando-o para modificação de dados

Depois que o ObjectDataSource tiver sido adicionado à página e configurado, estamos prontos para adicionar controles da Web de dados à página para exibir os dados e fornecer um meio para o usuário final modificá-lo. Veremos o GridView, o DetailsView e o FormView separadamente, pois esses controles da Web de dados diferem em suas configurações e recursos de modificação de dados.

Como veremos no restante deste artigo, adicionar suporte a edição, inserção e exclusão muito básicos por meio dos controles GridView, DetailsView e FormView é realmente tão simples quanto marcar algumas caixas de seleção. Há muitas sutilezas e casos de borda no mundo real que tornam essa funcionalidade mais envolvida do que apenas apontar e clicar. No entanto, este tutorial se concentra exclusivamente na prova de recursos de modificação de dados simplista. Os tutoriais futuros examinarão as preocupações que, sem dúvida, surgirão em uma configuração do mundo real.

Excluindo dados do GridView

Comece arrastando um GridView da caixa de ferramentas para o designer. Em seguida, associe o ObjectDataSource ao GridView selecionando-o na lista suspensa na marca inteligente do GridView. Neste ponto, a marcação declarativa do GridView será:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:BoundField DataField="ProductID" HeaderText="ProductID"
            InsertVisible="False"
            ReadOnly="True" SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName" HeaderText="ProductName"
            SortExpression="ProductName" />
        <asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
           SortExpression="SupplierID" />
        <asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
           SortExpression="CategoryID" />
        <asp:BoundField DataField="QuantityPerUnit"
           HeaderText="QuantityPerUnit"
           SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
           SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock"
           HeaderText="UnitsInStock" SortExpression="UnitsInStock" />
        <asp:BoundField DataField="UnitsOnOrder"
           HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" />
        <asp:BoundField DataField="ReorderLevel"
           HeaderText="ReorderLevel" SortExpression="ReorderLevel" />
        <asp:CheckBoxField DataField="Discontinued"
           HeaderText="Discontinued" SortExpression="Discontinued" />
        <asp:BoundField DataField="CategoryName"
           HeaderText="CategoryName" ReadOnly="True"
            SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName"
            HeaderText="SupplierName" ReadOnly="True"
            SortExpression="SupplierName" />
    </Columns>
</asp:GridView>

Associar o GridView ao ObjectDataSource por meio de sua marca inteligente tem dois benefícios:

  • Os BoundFields e CheckBoxFields são criados automaticamente para cada um dos campos retornados pelo ObjectDataSource. Além disso, as propriedades BoundField e CheckBoxField são definidas com base nos metadados do campo subjacente. Por exemplo, os campos ProductID, CategoryNamee SupplierName são marcados como somente leitura no ProductsDataTable e, portanto, não devem ser atualizáveis durante a edição. Para acomodar isso, as propriedades ReadOnly de boundfields são definidas como true.
  • A propriedade DataKeyNames é atribuída aos campos de chave primária do objeto subjacente. Isso é essencial ao usar o GridView para editar ou excluir dados, pois essa propriedade indica o campo (ou conjunto de campos) que identifica exclusivamente cada registro. Para obter mais informações sobre a propriedade DataKeyNames, consulte o mestre/detalhes usando um GridView mestre selecionável com um tutorial de detalhes detailview .

Embora o GridView possa ser associado ao ObjectDataSource por meio da sintaxe janela Propriedades ou declarativa, fazer isso exige que você adicione manualmente a marcação de BoundField e DataKeyNames apropriada.

O controle GridView fornece suporte interno para edição e exclusão em nível de linha. Configurar um GridView para dar suporte à exclusão adiciona uma coluna de botões de exclusão. Quando o usuário final clica no botão excluir para uma linha específica, um postback massacre e o GridView executa as seguintes etapas:

  1. Os valores de DeleteParameters do ObjectDataSource são atribuídos
  2. O método de Delete() do ObjectDataSource é invocado, excluindo o registro especificado
  3. O GridView se reassocia ao ObjectDataSource invocando seu método de Select()

Os valores atribuídos à DeleteParameters são os valores dos campos de DataKeyNames para a linha cujo botão de exclusão foi clicado. Portanto, é vital que a propriedade DataKeyNames de um GridView seja definida corretamente. Se ele estiver ausente, o DeleteParameters será atribuído a um valor de null na etapa 1, que por sua vez não resultará em quaisquer registros excluídos na etapa 2.

Note

A coleção de DataKeys é armazenada no estado de controle GridView s, o que significa que os valores de DataKeys serão lembrados por postagem, mesmo que o estado de exibição de GridView s tenha sido desabilitado. No entanto, é muito importante que o estado de exibição permaneça habilitado para GridViews que dão suporte à edição ou exclusão (o comportamento padrão). Se você definir a Propriedade GridView s EnableViewState como false, o comportamento de edição e exclusão funcionará bem para um único usuário, mas se houver usuários simultâneos excluindo dados, existirá a possibilidade de que esses usuários simultâneos excluam ou editem os registros que não pretendiam. Consulte minha entrada de blog, AVISO: problema de simultaneidade com ASP.NET 2,0 GridViews/DetailsView/formviews que dão suporte à edição e/ou exclusão e cujo estado de exibição está desabilitado, para obter mais informações.

Esse mesmo aviso também se aplica a DetailsViews e FormViews.

Para adicionar recursos de exclusão a um GridView, basta ir para sua marca inteligente e marcar a caixa de seleção Habilitar exclusão.

Marque a caixa de seleção Habilitar exclusão

Figura 10: marque a caixa de seleção Habilitar exclusão

Marcar a caixa de seleção Habilitar exclusão da marca inteligente adiciona um CommandField ao GridView. O CommandField renderiza uma coluna no GridView com botões para executar uma ou mais das seguintes tarefas: selecionando um registro, editando um registro e excluindo um registro. Vimos anteriormente o CommandField em ação com a seleção de registros no mestre/detalhes usando um GridView mestre selecionável com um tutorial de detalhes detailview .

O CommandField contém um número de ShowXButton propriedades que indicam qual série de botões são exibidos no comando. Marcando a caixa de seleção Habilitar exclusão, um CommandField cujo ShowDeleteButton propriedade é true foi adicionado à coleção de colunas do GridView.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" />
        ... BoundFields removed for brevity ...
    </Columns>
</asp:GridView>

Neste ponto, acredite ou não, concluimos a adição de suporte à exclusão ao GridView! Como mostra a Figura 11, ao visitar esta página por meio de um navegador, uma coluna de botões de exclusão está presente.

o CommandField adiciona uma coluna de botões excluir

Figura 11: o CommandField adiciona uma coluna de botões Delete (clique para exibir a imagem em tamanho normal)

Se você já está criando este tutorial do zero por conta própria, ao testar esta página, clicar no botão excluir gerará uma exceção. Continue lendo para saber por que essas exceções foram geradas e como corrigi-las.

Note

Se você estiver seguindo usando o download que acompanha este tutorial, esses problemas já foram contados. No entanto, recomendo que você leia os detalhes listados abaixo para ajudar a identificar problemas que podem surgir e soluções alternativas adequadas.

Se, ao tentar excluir um produto, você receber uma exceção cuja mensagem é semelhante a "ObjectDataSource"ObjectDataSource1 "não foi possível encontrar um método não genérico" DeleteProduct "que tenha parâmetros: ProductID, original_ProductID," você provavelmente esqueceu de remover a propriedade OldValuesParameterFormatString de ObjectDataSource. Com a propriedade OldValuesParameterFormatString especificada, o ObjectDataSource tenta passar os parâmetros de entrada productID e original_ProductID para o método DeleteProduct. o DeleteProduct, no entanto, só aceita um único parâmetro de entrada, portanto, a exceção. Remover a propriedade OldValuesParameterFormatString (ou defini-la como {0}) instrui o ObjectDataSource a não tentar passar o parâmetro de entrada original.

garantir que a propriedade OldValuesParameterFormatString foi apagada

Figura 12: Verifique se a propriedade OldValuesParameterFormatString foi apagada (clique para exibir a imagem em tamanho normal)

Mesmo que você tenha removido a propriedade OldValuesParameterFormatString, você ainda receberá uma exceção ao tentar excluir um produto com a mensagem: "a instrução DELETE entrou em conflito com a ordem de referência ' FK_Order_detalhes_produtos ' ." O banco de dados Northwind contém uma restrição FOREIGN KEY entre a Order Details e a tabela Products, o que significa que um produto não poderá ser excluído do sistema se houver um ou mais registros para ele na tabela Order Details. Como cada produto no banco de dados Northwind tem pelo menos um registro no Order Details, não podemos excluir nenhum produto até que primeiro exclua os registros de detalhes do pedido associado do produto.

uma restrição FOREIGN KEY proíbe a exclusão de produtos

Figura 13: uma restrição FOREIGN KEY proíbe a exclusão de produtos (clique para exibir a imagem em tamanho normal)

Para nosso tutorial, vamos apenas excluir todos os registros da tabela Order Details. Em um aplicativo do mundo real, precisaremos:

  • Ter outra tela para gerenciar informações de detalhes do pedido
  • Aumentar o método de DeleteProduct para incluir a lógica para excluir os detalhes do pedido do produto especificado
  • Modificar a consulta SQL usada pelo TableAdapter para incluir a exclusão dos detalhes do pedido do produto especificado

Vamos apenas excluir todos os registros da tabela Order Details para burlar a restrição FOREIGN KEY. Vá para a Gerenciador de Servidores no Visual Studio, clique com o botão direito do mouse no nó NORTHWND.MDF e escolha nova consulta. Em seguida, na janela de consulta, execute a seguinte instrução SQL: DELETE FROM [Order Details]

excluir todos os registros da tabela detalhes do pedido

Figura 14: excluir todos os registros da tabela de Order Details (clique para exibir a imagem em tamanho normal)

Depois de limpar a tabela de Order Details, clicar no botão excluir excluirá o produto sem erros. Se clicar no botão excluir não excluir o produto, verifique se a propriedade DataKeyNames do GridView está definida como o campo de chave primária (ProductID).

Note

Ao clicar no botão excluir, um postback massacre e o registro são excluídos. Isso pode ser perigoso, pois é fácil clicar acidentalmente no botão excluir da linha errada. Em um futuro tutorial, veremos como adicionar uma confirmação do lado do cliente ao excluir um registro.

Editando dados com o GridView

Juntamente com a exclusão, o controle GridView também fornece suporte interno à edição em nível de linha. Configurar um GridView para dar suporte à edição adiciona uma coluna de botões de edição. Da perspectiva do usuário final, clicar no botão Editar de uma linha faz com que essa linha se torne editável, transformando as células em caixas de Textque contêm os valores existentes e substituindo o botão Editar pelos botões atualizar e cancelar. Depois de fazer as alterações desejadas, o usuário final pode clicar no botão atualizar para confirmar as alterações ou no botão Cancelar para descartá-las. Em ambos os casos, depois de clicar em atualizar ou cancelar o GridView retorna para seu estado de pré-edição.

Da nossa perspectiva como o desenvolvedor da página, quando o usuário final clica no botão Editar para uma linha específica, um postback massacre e o GridView executa as seguintes etapas:

  1. A propriedade EditItemIndex do GridView é atribuída ao índice da linha cujo botão de edição foi clicado
  2. O GridView se reassocia ao ObjectDataSource invocando seu método de Select()
  3. O índice de linha que corresponde ao EditItemIndex é renderizado no "modo de edição". Nesse modo, o botão Editar é substituído pelos botões Update e Cancel e BoundFields cujas propriedades ReadOnly são false (o padrão) são renderizadas como controles da Web TextBox cujas propriedades Text são atribuídas aos valores dos campos de dados.

Neste ponto, a marcação é retornada para o navegador, permitindo que o usuário final faça alterações nos dados da linha. Quando o usuário clica no botão atualizar, ocorre um postback e o GridView executa as seguintes etapas:

  1. Os valores de UpdateParameters do ObjectDataSource são atribuídos aos valor inseridos pelo usuário final na interface de edição do GridView
  2. O método de Update() do ObjectDataSource é invocado, atualizando o registro especificado
  3. O GridView se reassocia ao ObjectDataSource invocando seu método de Select()

Os valores de chave primária atribuídos ao UpdateParameters na etapa 1 vêm dos valores especificados na propriedade DataKeyNames, enquanto os valores de chave não primária são provenientes do texto nos controles da Web da caixa de texto para a linha editada. Assim como acontece com a exclusão, é vital que a propriedade DataKeyNames de um GridView seja definida corretamente. Se ele estiver ausente, o valor da chave primária UpdateParameters será atribuído a um valor de null na etapa 1, que por sua vez não resultará em nenhum registro atualizado na etapa 2.

A funcionalidade de edição pode ser ativada simplesmente marcando a caixa de seleção Habilitar edição na marca inteligente do GridView.

Marque a caixa de seleção Habilitar edição

Figura 15: marcar a caixa de seleção Habilitar edição

Marcar a caixa de seleção Habilitar edição adicionará um CommandField (se necessário) e definirá sua propriedade ShowEditButton como true. Como vimos anteriormente, o CommandField contém um número de ShowXButton propriedades que indicam qual série de botões são exibidos no comando. Marcar a caixa de seleção Habilitar edição adiciona a propriedade ShowEditButton ao CommandField existente:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowDeleteButton="True"
            ShowEditButton="True" />
        ... BoundFields removed for brevity ...
    </Columns>
</asp:GridView>

Isso é tudo o que é para adicionar suporte à edição rudimentar. Como mostra o Figure16, a interface de edição é, em vez de crua, cada BoundField cuja propriedade ReadOnly está definida como false (o padrão) é renderizada como uma caixa de texto. Isso inclui campos como CategoryID e SupplierID, que são chaves para outras tabelas.

clicar no botão Chai s Edit exibe a linha no modo de edição

Figura 16: clicar no botão Chai s Edit exibe a linha no modo de edição (clique para exibir a imagem em tamanho normal)

Além de solicitar aos usuários que editem valores de chave estrangeira diretamente, a interface da interface de edição não tem as seguintes maneiras:

  • Se o usuário inserir um CategoryID ou SupplierID que não exista no banco de dados, o UPDATE violará uma restrição FOREIGN KEY, fazendo com que uma exceção seja gerada.
  • A interface de edição não inclui nenhuma validação. Se você não fornecer um valor necessário (como ProductName) ou inserir um valor de cadeia de caracteres em que um valor numérico é esperado (como inserir "muito!" na caixa de texto UnitPrice), uma exceção será lançada. Um tutorial futuro examinará como adicionar controles de validação à interface do usuário de edição.
  • Atualmente, todos os campos de produto que não são somente leitura devem ser incluídos no GridView. Se tivéssemos de remover um campo do GridView, digamos UnitPrice, ao atualizar os dados, o GridView não definiria o valor de UpdateParameters de UnitPrice, que alteraria o UnitPrice do registro do banco de dados para um valor de NULL. Da mesma forma, se um campo obrigatório, como ProductName, for removido do GridView, a atualização falhará com a mesma "coluna ' ProductName ' não permite nulos" exceção mencionada acima.
  • A formatação da interface de edição deixa muito a desejar. O UnitPrice é mostrado com quatro pontos decimais. O ideal é que os valores CategoryID e SupplierID contenham DropDownLists que listem as categorias e os fornecedores no sistema.

Essas são todas as falhas com as quais teremos que viver por enquanto, mas serão abordadas em Tutoriais futuros.

Inserindo, editando e excluindo dados com o DetailsView

Como vimos nos tutoriais anteriores, o controle DetailsView exibe um registro de cada vez e, como o GridView, permite a edição e a exclusão do registro exibido no momento. A experiência do usuário final com edição e exclusão de itens de um DetailsView e o fluxo de trabalho do lado do ASP.NET é idêntica à do GridView. Onde o DetailsView difere do GridView é que ele também fornece suporte interno à inserção.

Para demonstrar os recursos de modificação de dados do GridView, comece adicionando um DetailsView à página de Basics.aspx acima do GridView existente e associe-o ao ObjectDataSource existente por meio da marca inteligente de DetailsView. Em seguida, desmarque as propriedades Height e Width de DetailsView e marque a opção habilitar paginação na marca inteligente. Para habilitar a edição, inserção e exclusão de suporte, basta marcar as caixas de seleção Habilitar edição, habilitar inserção e habilitar exclusão na marca inteligente.

Configurar o DetailsView para dar suporte à edição, inserção e exclusão

Figura 17: configurar o DetailsView para dar suporte à edição, inserção e exclusão

Assim como com o GridView, adicionar edição, inserção ou exclusão de suporte adiciona um CommandField ao DetailsView, como mostra a seguinte sintaxe declarativa:

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True">
    <Fields>
        <asp:BoundField DataField="ProductID"
            HeaderText="ProductID" InsertVisible="False"
            ReadOnly="True" SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName"
            HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
            SortExpression="SupplierID" />
        <asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
            SortExpression="CategoryID" />
        <asp:BoundField DataField="QuantityPerUnit"
            HeaderText="QuantityPerUnit"
            SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice"
            HeaderText="UnitPrice" SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock"
            HeaderText="UnitsInStock" SortExpression="UnitsInStock" />
        <asp:BoundField DataField="UnitsOnOrder"
            HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" />
        <asp:BoundField DataField="ReorderLevel"
            HeaderText="ReorderLevel" SortExpression="ReorderLevel" />
        <asp:CheckBoxField DataField="Discontinued"
            HeaderText="Discontinued" SortExpression="Discontinued" />
        <asp:BoundField DataField="CategoryName"
            HeaderText="CategoryName" ReadOnly="True"
            SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName"
            HeaderText="SupplierName" ReadOnly="True"
            SortExpression="SupplierName" />
        <asp:CommandField ShowDeleteButton="True"
            ShowEditButton="True" ShowInsertButton="True" />
    </Fields>
</asp:DetailsView>

Observe que para o DetailsView, o comando aparece no final da coleção de colunas por padrão. Como os campos de DetailsView são renderizados como linhas, o CommandField é exibido como uma linha com os botões inserir, editar e excluir na parte inferior do DetailsView.

configurar o DetailsView para dar suporte à edição, inserção e exclusão

Figura 18: configurar o DetailsView para dar suporte à edição, inserção e exclusão (clique para exibir a imagem em tamanho normal)

Clicar no botão excluir inicia a mesma sequência de eventos que com o GridView: um postback; seguido pelo DetailsView que preenche sua DeleteParameters de ObjectDataSource com base nos valores de DataKeyNames; e concluído com uma chamada de seu método de Delete() de ObjectDataSource, que, na verdade, remove o produto do banco de dados. A edição no DetailsView também funciona de maneira idêntica à do GridView.

Para inserção, o usuário final recebe um novo botão que, quando clicado, renderiza o DetailsView no "modo de inserção". Com o "modo de inserção", o novo botão é substituído pelos botões inserir e cancelar e somente os BoundFields cuja propriedade InsertVisible está definida como true (o padrão) são exibidos. Esses campos de dados identificados como campos de incremento automático, como ProductID, têm sua propriedade InsertVisible definida como false ao associar o DetailsView à fonte de dados por meio da marca inteligente.

Ao associar uma fonte de dados a um DetailsView por meio da marca inteligente, o Visual Studio define a propriedade InsertVisible como false somente para campos de incremento automático. Campos somente leitura, como CategoryName e SupplierName, serão exibidos na interface do usuário "modo de inserção", a menos que sua propriedade InsertVisible seja definida explicitamente como false. Reserve um momento para definir essas propriedades de InsertVisible de dois campos como false, por meio da sintaxe declarativa de DetailsView ou por meio do link editar campos na marca inteligente. A Figura 19 mostra a definição das propriedades de InsertVisible como false clicando no link editar campos.

Northwind Traders agora oferece a Acme chá

Figura 19: a Northwind Traders agora oferece a Acme chá (clique para exibir a imagem em tamanho normal)

Depois de definir as propriedades de InsertVisible, exiba a página de Basics.aspx em um navegador e clique no botão novo. A figura 20 mostra o DetailsView ao adicionar uma nova bebida, Acme chá, à nossa linha de produtos.

Northwind Traders agora oferece a Acme chá

Figura 20: a Northwind Traders agora oferece a Acme chá (clique para exibir a imagem em tamanho normal)

Depois de inserir os detalhes da Acme chá e clicar no botão Inserir, um postback massacre e o novo registro são adicionados à tabela Products banco de dados. Como este DetailsView lista os produtos na ordem em que eles existem na tabela de banco de dados, devemos paginar para o último produto a fim de ver o novo produto.

detalhes do chá de Acme

Figura 21: detalhes do chá de Acme (clique para exibir a imagem em tamanho normal)

Note

A propriedade CurrentMode de DetailsView indica a interface que está sendo exibida e pode ser um dos seguintes valores: Edit, Insertou ReadOnly. A Propriedade DefaultMode indica o modo em que o DetailsView retorna após uma edição ou inserção ter sido concluída e é útil para exibir um DetailsView que é permanentemente no modo Editar ou inserir.

Os recursos de inserção e edição de ponto e clique do DetailsView sofrem com as mesmas limitações que o GridView: o usuário deve inserir CategoryID existentes e valores de SupplierID por meio de uma caixa de texto; a interface não tem nenhuma lógica de validação; todos os campos de produto que não permitem NULL valores ou que não têm um valor padrão especificado no nível de banco de dados devem ser incluídos na interface de inserção e assim por diante.

As técnicas que examinaremos para estender e aprimorar a interface de edição de GridView em artigos futuros podem ser aplicadas às interfaces de edição e inserção do controle DetailsView também.

Usando o FormView para uma interface de usuário de modificação de dados mais flexível

O FormView oferece suporte interno para inserção, edição e exclusão de dados, mas como ele usa modelos em vez de campos, não há nenhum lugar para adicionar o BoundFields ou o CommandField usado pelos controles GridView e DetailsView para fornecer os dados interface de modificação. Em vez disso, essa interface os controles da Web para coletar entrada do usuário ao adicionar um novo item ou editar um existente juntamente com os botões novo, editar, excluir, inserir, atualizar e cancelar devem ser adicionados manualmente aos modelos apropriados. Felizmente, o Visual Studio criará automaticamente a interface necessária ao ligar o FormView a uma fonte de dados por meio da lista suspensa em sua marca inteligente.

Para ilustrar essas técnicas, comece adicionando um FormView à página Basics.aspx e, na marca inteligente do FormView, associe-o ao ObjectDataSource já criado. Isso irá gerar um EditItemTemplate, InsertItemTemplatee ItemTemplate para o FormView com controles da Web TextBox para coletar os botões de entrada e de botão da Web do usuário para os novos, editar, excluir, inserir, atualizar e cancelar. Além disso, a propriedade DataKeyNames do FormView é definida como o campo de chave primária (ProductID) do objeto retornado pelo ObjectDataSource. Por fim, marque a opção habilitar paginação na marca inteligente do FormView.

O seguinte mostra a marcação declarativa para o ItemTemplate do FormView após o FormView ter sido associado a ObjectDataSource. Por padrão, cada campo de produto de valor não booliano é associado à propriedade Text de um controle de rótulo da Web, enquanto cada campo de valor booliano (Discontinued) é associado à propriedade Checked de um controle da Web de caixa de seleção desabilitado. Para que os botões novo, editar e excluir disparem determinado comportamento de FormView quando clicados, é imperativo que seus CommandName valores sejam definidos como New, Edite Delete, respectivamente.

<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True">
    <EditItemTemplate>
        ...
    </EditItemTemplate>
    <InsertItemTemplate>
        ...
    </InsertItemTemplate>
    <ItemTemplate>
        ProductID:
        <asp:Label ID="ProductIDLabel" runat="server"
            Text='<%# Eval("ProductID") %>'></asp:Label><br />
        ProductName:
        <asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Bind("ProductName") %>'>
        </asp:Label><br />
        SupplierID:
        <asp:Label ID="SupplierIDLabel" runat="server"
            Text='<%# Bind("SupplierID") %>'>
        </asp:Label><br />
        CategoryID:
        <asp:Label ID="CategoryIDLabel" runat="server"
            Text='<%# Bind("CategoryID") %>'>
        </asp:Label><br />
        QuantityPerUnit:
        <asp:Label ID="QuantityPerUnitLabel" runat="server"
            Text='<%# Bind("QuantityPerUnit") %>'>
        </asp:Label><br />
        UnitPrice:
        <asp:Label ID="UnitPriceLabel" runat="server"
            Text='<%# Bind("UnitPrice") %>'></asp:Label><br />
        UnitsInStock:
        <asp:Label ID="UnitsInStockLabel" runat="server"
            Text='<%# Bind("UnitsInStock") %>'>
        </asp:Label><br />
        UnitsOnOrder:
        <asp:Label ID="UnitsOnOrderLabel" runat="server"
            Text='<%# Bind("UnitsOnOrder") %>'>
        </asp:Label><br />
        ReorderLevel:
        <asp:Label ID="ReorderLevelLabel" runat="server"
            Text='<%# Bind("ReorderLevel") %>'>
        </asp:Label><br />
        Discontinued:
        <asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
            Checked='<%# Bind("Discontinued") %>'
            Enabled="false" /><br />
        CategoryName:
        <asp:Label ID="CategoryNameLabel" runat="server"
            Text='<%# Bind("CategoryName") %>'>
        </asp:Label><br />
        SupplierName:
        <asp:Label ID="SupplierNameLabel" runat="server"
            Text='<%# Bind("SupplierName") %>'>
        </asp:Label><br />
        <asp:LinkButton ID="EditButton" runat="server"
            CausesValidation="False" CommandName="Edit"
            Text="Edit">
        </asp:LinkButton>
        <asp:LinkButton ID="DeleteButton" runat="server"
            CausesValidation="False" CommandName="Delete"
            Text="Delete">
        </asp:LinkButton>
        <asp:LinkButton ID="NewButton" runat="server"
            CausesValidation="False" CommandName="New"
            Text="New">
        </asp:LinkButton>
    </ItemTemplate>
</asp:FormView>

A Figura 22 mostra a ItemTemplate do FormView quando exibida por meio de um navegador. Cada campo de produto é listado com os botões novo, editar e excluir na parte inferior.

ItemTemplate padrão FormView lista cada campo de produto juntamente com os botões novo, editar e excluir

Figura 22: o ItemTemplate FormView padrão lista cada campo de produto juntamente com os botões novo, editar e excluir (clique para exibir a imagem em tamanho normal)

Assim como com GridView e DetailsView, clicar no botão Delete ou em qualquer Button, LinkButton ou ImageButton cuja propriedade CommandName está definida como delete causa um postback, popula o DeleteParameters do ObjectDataSource com base no valor de DataKeyNames do FormView e invoca o método Delete() do ObjectDataSource.

Quando o botão Editar é clicado em um postback massacre e os dados são reassociados ao EditItemTemplate, o que é responsável por renderizar a interface de edição. Essa interface inclui os controles da Web para editar dados juntamente com os botões atualizar e cancelar. O EditItemTemplate padrão gerado pelo Visual Studio contém um rótulo para todos os campos de incremento automático (ProductID), uma caixa de texto para cada campo de valor não booliano e uma caixa de seleção para cada campo de valor booliano. Esse comportamento é muito semelhante aos BoundFields gerados automaticamente nos controles GridView e DetailsView.

Note

Um pequeno problema com a geração automática do FormView do EditItemTemplate é que ele processa controles da Web TextBox para os campos que são somente leitura, como CategoryName e SupplierName. Veremos como considerar isso em breve.

Os controles de caixa de texto no EditItemTemplate têm sua propriedade Text associada ao valor de seu campo de dados correspondente usando DataBinding bidirecional. A ligação de dados bidirecional, denotada por <%# Bind("dataField") %>, executa DataBinding ao associar dados ao modelo e ao preencher os parâmetros de ObjectDataSource para inserção ou edição de registros. Ou seja, quando o usuário clica no botão Editar na ItemTemplate, o método Bind() retorna o valor do campo de dados especificado. Depois que o usuário faz suas alterações e clica em atualizar, os valores postados que correspondem aos campos de dados especificados usando Bind() são aplicados à UpdateParametersde ObjectDataSource. Como alternativa, DataBinding unidirecional, indicada por <%# Eval("dataField") %>, recupera apenas os valores de campo de dados ao vincular dados ao modelo e não retorna os valores inseridos pelo usuário para os parâmetros da fonte de dados no postback.

A marcação declarativa a seguir mostra o EditItemTemplatedo FormView. Observe que o método Bind() é usado na sintaxe DataBinding aqui e que os controles da Web do botão Update e Cancel têm suas propriedades CommandName definidas adequadamente.

<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True">
    <EditItemTemplate>
        ProductID:
        <asp:Label ID="ProductIDLabel1" runat="server"
          Text="<%# Eval("ProductID") %>"></asp:Label><br />
        ProductName:
        <asp:TextBox ID="ProductNameTextBox" runat="server"
          Text="<%# Bind("ProductName") %>">
        </asp:TextBox><br />
        SupplierID:
        <asp:TextBox ID="SupplierIDTextBox" runat="server"
          Text="<%# Bind("SupplierID") %>">
        </asp:TextBox><br />
        CategoryID:
        <asp:TextBox ID="CategoryIDTextBox" runat="server"
          Text="<%# Bind("CategoryID") %>">
        </asp:TextBox><br />
        QuantityPerUnit:
        <asp:TextBox ID="QuantityPerUnitTextBox" runat="server"
           Text="<%# Bind("QuantityPerUnit") %>">
        </asp:TextBox><br />
        UnitPrice:
        <asp:TextBox ID="UnitPriceTextBox" runat="server"
           Text="<%# Bind("UnitPrice") %>">
        </asp:TextBox><br />
        UnitsInStock:
        <asp:TextBox ID="UnitsInStockTextBox" runat="server"
           Text="<%# Bind("UnitsInStock") %>">
        </asp:TextBox><br />
        UnitsOnOrder:
        <asp:TextBox ID="UnitsOnOrderTextBox" runat="server"
           Text="<%# Bind("UnitsOnOrder") %>">
        </asp:TextBox><br />
        ReorderLevel:
        <asp:TextBox ID="ReorderLevelTextBox" runat="server"
           Text="<%# Bind("ReorderLevel") %>">
        </asp:TextBox><br />
        Discontinued:
        <asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
            Checked="<%# Bind("Discontinued") %>" /><br />
        CategoryName:
        <asp:TextBox ID="CategoryNameTextBox" runat="server"
             Text="<%# Bind("CategoryName") %>">
        </asp:TextBox><br />
        SupplierName:
        <asp:TextBox ID="SupplierNameTextBox" runat="server"
             Text="<%# Bind("SupplierName") %>">
        </asp:TextBox><br />
        <asp:LinkButton ID="UpdateButton" runat="server"
            CausesValidation="True" CommandName="Update"
            Text="Update">
        </asp:LinkButton>
        <asp:LinkButton ID="UpdateCancelButton" runat="server"
            CausesValidation="False" CommandName="Cancel"
            Text="Cancel">
        </asp:LinkButton>
    </EditItemTemplate>
    <InsertItemTemplate>
        ...
    </InsertItemTemplate>
    <ItemTemplate>
        ...
    </ItemTemplate>
</asp:FormView>

Nosso EditItemTemplate, neste ponto, fará com que uma exceção seja gerada se tentarmos usá-la. O problema é que os campos CategoryName e SupplierName são renderizados como controles da Web TextBox no EditItemTemplate. Precisamos alterar esses TextBoxes para rótulos ou removê-los completamente. Vamos simplesmente excluí-los totalmente da EditItemTemplate.

A Figura 23 mostra o FormView em um navegador depois que o botão de edição é clicado para Chai. Observe que os campos SupplierName e CategoryName mostrados no ItemTemplate não estão mais presentes, pois nós acabamos de removê-los do EditItemTemplate. Quando o botão de atualização é clicado, o FormView prossegue na mesma sequência de etapas que os controles GridView e DetailsView.

por padrão, o EditItemTemplate mostra cada campo de produto editável como uma caixa de texto ou caixa de seleção

Figura 23: por padrão, a EditItemTemplate mostra cada campo de produto editável como uma caixa de texto ou caixa de seleção (clique para exibir a imagem em tamanho normal)

Quando o botão de inserção é clicado, o ItemTemplate do FormView é um massacre de postback. No entanto, nenhum dado é associado ao FormView porque um novo registro está sendo adicionado. A interface InsertItemTemplate inclui os controles da Web para adicionar um novo registro junto com os botões inserir e cancelar. O InsertItemTemplate padrão gerado pelo Visual Studio contém uma caixa de texto para cada campo de valor não booliano e uma caixa de seleção para cada campo de valor booliano, semelhante à interface de EditItemTemplategerada automaticamente. Os controles TextBox têm sua propriedade Text associada ao valor de seu campo de dados correspondente usando DataBinding bidirecional.

A marcação declarativa a seguir mostra o InsertItemTemplatedo FormView. Observe que o método Bind() é usado na sintaxe DataBinding aqui e que os controles da Web do botão Inserir e cancelar têm suas propriedades CommandName definidas adequadamente.

<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True">
    <EditItemTemplate>
        ...
    </EditItemTemplate>
    <InsertItemTemplate>
        ProductName:
        <asp:TextBox ID="ProductNameTextBox" runat="server"
           Text="<%# Bind("ProductName") %>">
        </asp:TextBox><br />
        SupplierID:
        <asp:TextBox ID="SupplierIDTextBox" runat="server"
           Text="<%# Bind("SupplierID") %>">
        </asp:TextBox><br />
        CategoryID:
        <asp:TextBox ID="CategoryIDTextBox" runat="server"
           Text="<%# Bind("CategoryID") %>">
        </asp:TextBox><br />
        QuantityPerUnit:
        <asp:TextBox ID="QuantityPerUnitTextBox" runat="server"
           Text="<%# Bind("QuantityPerUnit") %>">
        </asp:TextBox><br />
        UnitPrice:
        <asp:TextBox ID="UnitPriceTextBox" runat="server"
           Text="<%# Bind("UnitPrice") %>">
        </asp:TextBox><br />
        UnitsInStock:
        <asp:TextBox ID="UnitsInStockTextBox" runat="server"
           Text="<%# Bind("UnitsInStock") %>">
        </asp:TextBox><br />
        UnitsOnOrder:
        <asp:TextBox ID="UnitsOnOrderTextBox" runat="server"
           Text="<%# Bind("UnitsOnOrder") %>">
        </asp:TextBox><br />
        ReorderLevel:
        <asp:TextBox ID="ReorderLevelTextBox" runat="server"
           Text="<%# Bind("ReorderLevel") %>">
        </asp:TextBox><br />
        Discontinued:
        <asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
           Checked="<%# Bind("Discontinued") %>" /><br />
        CategoryName:
        <asp:TextBox ID="CategoryNameTextBox" runat="server"
            Text="<%# Bind("CategoryName") %>">
        </asp:TextBox><br />
        SupplierName:
        <asp:TextBox ID="SupplierNameTextBox" runat="server"
           Text="<%# Bind("SupplierName") %>">
        </asp:TextBox><br />
        <asp:LinkButton ID="InsertButton" runat="server"
            CausesValidation="True" CommandName="Insert"
            Text="Insert">
        </asp:LinkButton>
        <asp:LinkButton ID="InsertCancelButton" runat="server"
            CausesValidation="False" CommandName="Cancel"
            Text="Cancel">
        </asp:LinkButton>
    </InsertItemTemplate>
    <ItemTemplate>
        ...
    </ItemTemplate>
</asp:FormView>

Há uma sutileza com a geração automática do FormView do InsertItemTemplate. Especificamente, os controles da Web TextBox são criados mesmo para aqueles campos que são somente leitura, como CategoryName e SupplierName. Assim como com o EditItemTemplate, precisamos remover essas caixas de textdas InsertItemTemplate.

A figura 24 mostra o FormView em um navegador ao adicionar um novo produto, Acme Coffee. Observe que os campos SupplierName e CategoryName mostrados no ItemTemplate não estão mais presentes, pois nós acabamos de removê-los. Quando o botão de inserção é clicado, o FormView prossegue na mesma sequência de etapas que o controle DetailsView, adicionando um novo registro à tabela Products. A figura 25 mostra os detalhes do produto da Acme Coffee no FormView depois que ele é inserido.

o InsertItemTemplate determina a interface de inserção do FormView

Figura 24: a InsertItemTemplate determina a interface de inserção do FormView (clique para exibir a imagem em tamanho normal)

os detalhes do novo produto, Acme Coffee, são exibidos no FormView

Figura 25: os detalhes do novo produto, Acme Coffee, são exibidos no FormView (clique para exibir a imagem em tamanho normal)

Ao separar as interfaces somente leitura, editar e inserir em três modelos separados, o FormView permite um grau mais preciso de controle sobre essas interfaces do que o DetailsView e o GridView.

Note

Como o DetailsView, a propriedade CurrentMode do FormView indica a interface que está sendo exibida e sua propriedade DefaultMode indica o modo que FormView retorna após uma edição ou inserção ser concluída.

Resumo

Neste tutorial, examinamos as noções básicas de inserção, edição e exclusão de dados usando GridView, DetailsView e FormView. Todos esses três controles fornecem algum nível de recursos de modificação de dados internos que podem ser utilizados sem escrever uma única linha de código na página ASP.NET graças aos controles da Web de dados e ao ObjectDataSource. No entanto, as técnicas simples de ponto e clique renderizam uma interface do usuário de modificação de dados bastante Frail e ingênua. Para fornecer validação, injetar valores programáticos, tratar exceções normalmente, personalizar a interface do usuário e assim por diante, precisaremos contar com uma apresentação de técnicas que serão discutidas nos próximos vários tutoriais.

Boa programação!

Sobre o autor

Scott Mitchell, autor de sete livros sobre ASP/ASP. net e fundador da 4guysfromrolla.com, tem trabalhado com tecnologias Web da Microsoft desde 1998. Scott trabalha como consultor, instrutor e escritor independentes. Seu livro mais recente é que a Sams ensina a ASP.NET 2,0 em 24 horas. Ele pode ser acessado em mitchell@4GuysFromRolla.com. ou por meio de seu blog, que pode ser encontrado em http://ScottOnWriting.NET.