Compartilhar via


Introdução ASP.NET páginas da Web - Excluindo dados do banco de dados

por Tom FitzMacken

Este tutorial mostra como excluir uma entrada de banco de dados individual. Ele pressupõe que você tenha concluído a série por meio da atualização de dados do banco de dados em ASP.NET páginas da Web.

O que você aprenderá:

  • Como selecionar um registro individual de uma lista de registros.
  • Como excluir um único registro de um banco de dados.
  • Como verificar se um botão específico foi clicado em um formulário.

Recursos/tecnologias discutidos:

  • O WebGrid ajudante.
  • O comando SQL Delete .
  • O Database.Execute método para executar um comando SQL Delete .

O que você vai construir

No tutorial anterior, você aprendeu a atualizar um registro de banco de dados existente. Este tutorial é semelhante, exceto que, em vez de atualizar o registro, você o excluirá. Os processos são praticamente os mesmos, exceto que a exclusão é mais simples, então este tutorial será curto.

Na página Filmes, você atualizará o WebGrid auxiliar para que ele exiba um link Excluir ao lado de cada filme para acompanhar o link Editar adicionado anteriormente.

Página Filmes mostrando um link Excluir para cada filme

Assim como na edição, quando você clica no link Excluir , ele leva você a uma página diferente, onde as informações do filme já estão em um formulário:

Excluir página de filme com um filme exibido

Você pode clicar no botão para excluir o registro permanentemente.

Você começará adicionando um link Excluir ao WebGrid auxiliar. Este link é semelhante ao link Editar que você adicionou em um tutorial anterior.

Abra o arquivo Movies.cshtml .

Altere a WebGrid marcação no corpo da página adicionando uma coluna. Aqui está a marcação modificada:

@grid.GetHtml(
    tableStyle: "grid",
    headerStyle: "head",
    alternatingRowStyle: "alt",
    columns: grid.Columns(
grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
grid.Column("Title"),
grid.Column("Genre"),
grid.Column("Year"),
grid.Column(format: @<a href="~/DeleteMovie?id=@item.ID">Delete</a>)
    )
)

A nova coluna é esta:

grid.Column(format: @<a href="~/DeleteMovie?id=@item.ID">Delete</a>)

Da maneira como a grade está configurada, a coluna Editar está mais à esquerda na grade e a coluna Excluir está mais à direita. (Há uma vírgula após a Year coluna agora, caso você não tenha notado isso.) Não há nada de especial sobre para onde vão essas colunas de links, e você pode facilmente colocá-las uma ao lado da outra. Nesse caso, eles são separados para torná-los mais difíceis de se misturar.

Página Filmes com links Editar e Detalhes marcados para mostrar que eles não estão próximos um do outro

A nova coluna mostra um link (<a> elemento) cujo texto diz "Excluir". O destino do link (seu href atributo) é o código que, em última análise, resolve para algo como este URL, com o id valor diferente para cada filme:

http://localhost:43097/DeleteMovie?id=7

Esse link invocará uma página chamada DeleteMovie e passará a ID do filme que você selecionou.

Este tutorial não entrará em detalhes sobre como esse link é construído, pois é quase idêntico ao link Editar do tutorial anterior (Atualizando dados de banco de dados em ASP.NET páginas da Web).

Criando a página de exclusão

Agora você pode criar a página que será o destino do link Excluir na grade.

Observação

Importante A técnica de primeiro selecionar um registro para excluir e, em seguida, usar uma página e um botão separados para confirmar o processo é extremamente importante para a segurança. Como você leu em tutoriais anteriores, fazer qualquer tipo de alteração em seu site deve sempre ser feito usando um formulário — ou seja, usando uma operação HTTP POST. Se você tornou possível alterar o site apenas clicando em um link (ou seja, usando uma operação GET), as pessoas poderiam fazer solicitações simples ao seu site e excluir seus dados. Mesmo um rastreador de mecanismo de pesquisa que está indexando seu site pode excluir dados inadvertidamente apenas seguindo os links.

Quando seu aplicativo permite que as pessoas alterem um registro, você precisa apresentá-lo ao usuário para edição de qualquer maneira. Mas você pode ficar tentado a pular esta etapa para excluir um registro. Não pule essa etapa, no entanto. (Também é útil para os usuários verem o registro e confirmarem que estão excluindo o registro pretendido.)

Em um conjunto de tutoriais subsequente, você verá como adicionar a funcionalidade de logon para que um usuário tenha que fazer logon antes de excluir um registro.

Crie uma página chamada DeleteMovie.cshtml e substitua o que está no arquivo pela seguinte marcação:

<html>
<head>
  <title>Delete a Movie</title>
</head>
<body>
      <h1>Delete a Movie</h1>
        @Html.ValidationSummary()
      <p><a href="~/Movies">Return to movie listing</a></p>

      <form method="post">
        <fieldset>
        <legend>Movie Information</legend>

        <p><span>Title:</span>
         <span>@title</span></p>

        <p><span>Genre:</span>
         <span>@genre</span></p>

        <p><span>Year:</span>
          <span>@year</span></p>

        <input type="hidden" name="movieid" value="@movieId" />
        <p><input type="submit" name="buttonDelete" value="Delete Movie" /></p>
        </fieldset>
      </form>
    </body>
</html>

Essa marcação é como as páginas EditMovie , exceto que, em vez de usar caixas de texto (<input type="text">), a marcação inclui <span> elementos. Não há nada aqui para editar. Tudo o que você precisa fazer é exibir os detalhes do filme para que os usuários possam ter certeza de que estão excluindo o filme correto.

A marcação já contém um link que permite que o usuário retorne à página de listagem de filmes.

Como na página EditMovie , a ID do filme selecionado é armazenada em um campo oculto. (Ele é passado para a página em primeiro lugar como um valor de cadeia de caracteres de consulta.) Há uma Html.ValidationSummary chamada que exibirá erros de validação. Nesse caso, o erro pode ser que nenhum ID de filme foi passado para a página ou que o ID do filme é inválido. Essa situação pode ocorrer se alguém executou esta página sem primeiro selecionar um filme na página Filmes .

A legenda do botão é Excluir filme e seu atributo de nome é definido como buttonDelete. O name atributo será usado no código para identificar o botão que enviou o formulário.

Você terá que escrever código para 1) ler os detalhes do filme quando a página for exibida pela primeira vez e 2) realmente excluir o filme quando o usuário clicar no botão.

Adicionando código para ler um único filme

Na parte superior da página DeleteMovie.cshtml , adicione o seguinte bloco de código:

@{
    var title = "";
    var genre = "";
    var year = "";
    var movieId = "";

    if(!IsPost){
        if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()){
            movieId = Request.QueryString["ID"];
            var db = Database.Open("WebPagesMovies");
            var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
            var row = db.QuerySingle(dbCommand, movieId);
            if(row != null) {
                title = row.Title;
                genre = row.Genre;
                year = row.Year;
            }
            else{
                Validation.AddFormError("No movie was found for that ID.");
            }
        }
        else{
            Validation.AddFormError("No movie was found for that ID.");
        }
    }
}

Essa marcação é igual ao código correspondente na página EditMovie . Ele obtém a ID do filme da cadeia de caracteres de consulta e usa a ID para ler um registro do banco de dados. O código inclui o teste de validação (IsInt() e row != null) para garantir que o ID do filme que está sendo passado para a página seja válido.

Lembre-se de que esse código só deve ser executado na primeira vez que a página for executada. Você não deseja reler o registro de filme do banco de dados quando o usuário clicar no botão Excluir Filme . Portanto, o código para ler o filme está dentro de um teste que diz if(!IsPost) — ou seja, se a solicitação não é uma pós-operação (envio de formulário).

Adicionar código para excluir o filme selecionado

Para excluir o filme quando o usuário clicar no botão, adicione o seguinte código dentro da chave de fechamento do @ bloco:

if(IsPost && !Request["buttonDelete"].IsEmpty()){
    movieId = Request.Form["movieId"];
    var db = Database.Open("WebPagesMovies");
    var deleteCommand = "DELETE FROM Movies WHERE ID = @0";
    db.Execute(deleteCommand, movieId);
    Response.Redirect("~/Movies");
}

Esse código é semelhante ao código para atualizar um registro existente, mas mais simples. O código basicamente executa uma instrução SQL Delete .

Como na página EditMovie , o código está em um if(IsPost) bloco. Desta vez, a if() condição é um pouco mais complicada:

if(IsPost && !Request["buttonDelete"].IsEmpty())

Existem duas condições aqui. A primeira é que a página está sendo enviada, como você viu antes - if(IsPost).

A segunda condição é !Request["buttonDelete"].IsEmpty(), o que significa que a solicitação tem um objeto chamado buttonDelete. É certo que é uma forma indireta de testar qual botão enviou o formulário. Se um formulário contiver vários botões de envio, somente o nome do botão clicado aparecerá na solicitação. Portanto, logicamente, se o nome de um botão específico aparecer na solicitação — ou conforme declarado no código, se esse botão não estiver vazio — esse é o botão que enviou o formulário.

O && operador significa "e" (E lógico). Portanto, toda if a condição é ...

Esta solicitação é uma postagem (não uma solicitação inicial)

AND

O buttonDeletebotão era o botão que enviava o formulário.

Este formulário (na verdade, esta página) contém apenas um botão, portanto, o teste adicional para buttonDelete não é tecnicamente necessário. Ainda assim, você está prestes a executar uma operação que removerá dados permanentemente. Portanto, você deseja ter o máximo de certeza possível de que está executando a operação somente quando o usuário a solicitou explicitamente. Por exemplo, suponha que você expandiu esta página mais tarde e adicionou outros botões a ela. Mesmo assim, o código que exclui o filme será executado somente se o buttonDelete botão for clicado.

Como na página EditMovie , você obtém a ID do campo oculto e executa o comando SQL. A sintaxe da Delete instrução é:

DELETE FROM table WHERE ID = value

É vital incluir a WHERE cláusula e o ID. Se você deixar de fora a cláusula WHERE, todos os registros da tabela serão excluídos. Como você viu, você passa o valor da ID para o comando SQL usando um espaço reservado.

Testando o processo de exclusão de filme

Agora você pode testar. Execute a página Filmes e clique em Excluir ao lado de um filme. Quando a página DeleteMovie for exibida, clique em Excluir filme.

Excluir página Filme com o botão Excluir Filme destacado

Quando você clica no botão, o código exclui os filmes e retorna à lista de filmes. Lá você pode pesquisar o filme excluído e confirmar que ele foi excluído.

A seguir

O próximo tutorial mostra como dar a todas as páginas do seu site uma aparência e um layout comuns.

@{
    var db = Database.Open("WebPagesMovies") ;
    var selectCommand = "SELECT * FROM Movies";
    var searchTerm = "";

    if(!Request.QueryString["searchGenre"].IsEmpty() ) {
        selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
        searchTerm = Request.QueryString["searchGenre"];
    }

    if(!Request.QueryString["searchTitle"].IsEmpty() ) {
      selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
      searchTerm = "%" + Request.QueryString["searchTitle"] + "%";
    }

    var selectedData = db.Query(selectCommand, searchTerm);
    var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3);
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Movies</title>
      <style type="text/css">
        .grid { margin: 4px; border-collapse: collapse; width: 600px; }
        .grid th, .grid td { border: 1px solid #C0C0C0; padding: 5px; }
        .head { background-color: #E8E8E8; font-weight: bold; color: #FFF; }
        .alt { background-color: #E8E8E8; color: #000; }
      </style>
    </head>
    <body>
      <h1>Movies</h1>
      <form method="get">
        <div>
          <label for="searchGenre">Genre to look for:</label>
          <input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />
          <input type="Submit" value="Search Genre" /><br/>
          (Leave blank to list all movies.)<br/>
          </div>

        <div>
          <label for="SearchTitle">Movie title contains the following:</label>
          <input type="text" name="searchTitle" value="@Request.QueryString["searchTitle"]" />
          <input type="Submit" value="Search Title" /><br/>
        </div>

      </form>
        <div>
          @grid.GetHtml(
            tableStyle: "grid",
            headerStyle: "head",
            alternatingRowStyle: "alt",
            columns: grid.Columns(
                grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
                grid.Column("Title"),
                grid.Column("Genre"),
                grid.Column("Year"),
                grid.Column(format: @<a href="~/DeleteMovie?id=@item.ID">Delete</a>)
            )
        )
      </div>
      <p>
        <a href="~/AddMovie">Add a movie</a>
      </p>
    </body>
</html>

Listagem completa da página DeleteMovie

@{
    var title = "";
    var genre = "";
    var year = "";
    var movieId = "";

    if(!IsPost){
        if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()){
            movieId = Request.QueryString["ID"];
            var db = Database.Open("WebPagesMovies");
            var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
            var row = db.QuerySingle(dbCommand, movieId);
            if(row != null) {
                title = row.Title;
                genre = row.Genre;
                year = row.Year;
            }
            else{
                Validation.AddFormError("No movie was found for that ID.");
            }
        }
        else{
            Validation.AddFormError("No movie was found for that ID.");
        }
    }

    if(IsPost && !Request["buttonDelete"].IsEmpty()){
        movieId = Request.Form["movieId"];
        var db = Database.Open("WebPagesMovies");
        var deleteCommand = "DELETE FROM Movies WHERE ID = @0";
        db.Execute(deleteCommand, movieId);
        Response.Redirect("~/Movies");
    }
}
<html>
<head>
  <title>Delete a Movie</title>
</head>
<body>
      <h1>Delete a Movie</h1>
        @Html.ValidationSummary()
      <p><a href="~/Movies">Return to movie listing</a></p>

      <form method="post">
        <fieldset>
        <legend>Movie Information</legend>

        <p><span>Title:</span>
         <span>@title</span></p>

        <p><span>Genre:</span>
         <span>@genre</span></p>

        <p><span>Year:</span>
          <span>@year</span></p>

        <input type="hidden" name="movieid" value="@movieId" />
        <p><input type="submit" name="buttonDelete" value="Delete Movie" /></p>
        </fieldset>
        <p><a href="~/Movies">Return to movie listing</a></p>
      </form>
    </body>
</html>

Recursos adicionais