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 SQLDelete
.
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.
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:
Você pode clicar no botão para excluir o registro permanentemente.
Adicionando um link de exclusão à lista de filmes
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.
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 buttonDelete
botã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.
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.
Listagem completa da página do filme (atualizada com links de exclusão)
@{
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
- Introdução à programação da Web ASP.NET usando a sintaxe Razor
- Instrução SQL DELETE no site W3Schools