Compartilhar via


Pesquisar

Observação

Uma versão atualizada deste tutorial está disponível aqui usando a versão mais recente do Visual Studio. O novo tutorial usa ASP.NET Core MVC, que fornece muitas melhorias ao longo deste tutorial.

Este tutorial ensina a usar o ASP.NET Core MVC com controladores e exibições. O Razor Pages é uma nova alternativa no ASP.NET Core, um modelo de programação baseado em página que torna a criação da interface do usuário da Web mais fácil e produtiva. Recomendamos que você experimente o tutorial do Razor Pages antes da versão do MVC. O tutorial Páginas do Razor:

  • É mais fácil de acompanhar.
  • Aborda mais recursos.
  • É a abordagem preferencial para o desenvolvimento de novos aplicativos.

Adicionando um método de pesquisa e uma exibição de pesquisa

Nesta seção, você adicionará a funcionalidade de pesquisa ao Index método de ação que permite pesquisar filmes por gênero ou nome.

Pré-requisitos

Para corresponder às capturas de tela desta seção, você precisa executar o aplicativo (F5) e adicionar os filmes a seguir ao banco de dados.

Title Data de lançamento Gênero Preço
Ghostbusters 6/8/1984 Comédia 6,99
Caça-Fantasmas II 6/16/1989 Comédia 6,99
Planeta dos Macacos 3/27/1986 Ação 5,99

Atualizando o formulário de índice

Comece atualizando o método de Index ação para a classe existente MoviesController . O código é o seguinte:

public ActionResult Index(string searchString) 
{           
    var movies = from m in db.Movies 
                 select m; 
 
    if (!String.IsNullOrEmpty(searchString)) 
    { 
        movies = movies.Where(s => s.Title.Contains(searchString)); 
    } 
 
    return View(movies); 
}

A primeira linha do Index método cria a seguinte consulta LINQ para selecionar os filmes:

var movies = from m in db.Movies 
                 select m;

A consulta é definida neste ponto, mas ainda não foi executada no banco de dados.

Se o searchString parâmetro contiver uma cadeia de caracteres, a consulta movies será modificada para filtrar o valor da cadeia de caracteres de pesquisa, usando o seguinte código:

if (!String.IsNullOrEmpty(searchString)) 
{ 
    movies = movies.Where(s => s.Title.Contains(searchString)); 
}

O código s => s.Title acima é uma Expressão Lambda. Lambdas são usados em consultas LINQ baseadas em método como argumentos para métodos de operador de consulta padrão, como o método Where usado no código acima. As consultas LINQ não são executadas quando são definidas ou quando são modificadas chamando um método como Where ou OrderBy. Em vez disso, a execução da consulta é adiada, o que significa que a avaliação de uma expressão é atrasada até que seu valor realizado seja iterado ou o ToList método seja chamado. Search No exemplo, a consulta é executada na exibição Index.cshtml. Para obter mais informações sobre a execução de consulta adiada, consulte Execução da consulta.

Observação

O método Contains é executado no banco de dados, não no código c# acima. No banco de dados, Contém mapas para SQL LIKE, que não diferencia maiúsculas de minúsculas.

Agora você pode atualizar o Index modo de exibição que exibirá o formulário para o usuário.

Execute o aplicativo e navegue até /Movies/Index. Acrescente uma cadeia de consulta, como ?searchString=ghost, à URL. Os filmes filtrados são exibidos.

SearchQryStr

Se você alterar a assinatura do Index método para ter um parâmetro chamado id, o id parâmetro corresponderá ao {id} espaço reservado para as rotas padrão definidas no arquivo App_Start\RouteConfig.cs .

{controller}/{action}/{id}

O método original Index tem esta aparência:

public ActionResult Index(string searchString) 
{           
    var movies = from m in db.Movies 
                 select m; 
 
    if (!String.IsNullOrEmpty(searchString)) 
    { 
        movies = movies.Where(s => s.Title.Contains(searchString)); 
    } 
 
    return View(movies); 
}

O método modificado Index teria a seguinte aparência:

public ActionResult Index(string id) 
{ 
    string searchString = id; 
    var movies = from m in db.Movies 
                 select m; 
 
    if (!String.IsNullOrEmpty(searchString)) 
    { 
        movies = movies.Where(s => s.Title.Contains(searchString)); 
    } 
 
    return View(movies); 
}

Agora você pode passar o título de pesquisa como dados de rota (um segmento de URL), em vez de como um valor de cadeia de consulta.

Captura de tela que mostra a página Índice de Filmes do M VC. Host local dois-pontos 1 2 3 4 barra para a frente Filmes barra para frente índice barra para frente fantasma está no campo U R L e circulado em vermelho.

No entanto, você não pode esperar que os usuários modifiquem a URL sempre que desejarem pesquisar um filme. Portanto, agora você adicionará uma interface do usuário para ajudá-los a filtrar os filmes. Se você alterou a assinatura do Index método para testar como passar o parâmetro de ID associada à rota, altere-o de volta para que o Index método use um parâmetro de cadeia de caracteres chamado searchString:

public ActionResult Index(string searchString) 
{           
    var movies = from m in db.Movies 
                 select m; 
 
    if (!String.IsNullOrEmpty(searchString)) 
    { 
        movies = movies.Where(s => s.Title.Contains(searchString)); 
    } 
 
    return View(movies); 
}

Abra o arquivo Views\Movies\Index.cshtml e, logo após @Html.ActionLink("Create New", "Create"), adicione a marcação de formulário realçada abaixo:

@model IEnumerable<MvcMovie.Models.Movie> 
 
@{ 
    ViewBag.Title = "Index"; 
} 
 
<h2>Index</h2> 
 
<p> 
    @Html.ActionLink("Create New", "Create") 
     
     @using (Html.BeginForm()){    
         <p> Title: @Html.TextBox("SearchString") <br />   
         <input type="submit" value="Filter" /></p> 
        } 
</p>

O Html.BeginForm auxiliar cria uma marca de abertura <form> . O Html.BeginForm auxiliar faz com que o formulário seja postado para si mesmo quando o usuário envia o formulário clicando no botão Filtrar .

Visual Studio 2013 tem uma boa melhoria ao exibir e editar Exibir arquivos. Quando você executa o aplicativo com um arquivo de exibição aberto, Visual Studio 2013 invoca o método de ação do controlador correto para exibir a exibição.

Captura de tela que mostra a guia Índice dot c s h t m l e Gerenciador de Soluções aberta. Em Gerenciador de Soluções, a subpasta Filmes está aberta e Index dot c s h t m l está selecionado.

Com a exibição Índice aberta no Visual Studio (conforme mostrado na imagem acima), toque em Ctr F5 ou F5 para executar o aplicativo e tente pesquisar um filme.

Captura de tela que mostra a página Índice com um título inserido no campo Título.

Não há HttpPost sobrecarga do Index método . Você não precisa dele, pois o método não está alterando o estado do aplicativo, apenas filtrando dados.

Você poderá adicionar o método HttpPost Index a seguir. Nesse caso, o invocador de ação corresponderia ao HttpPost Index método e o HttpPost Index método seria executado conforme mostrado na imagem abaixo.

[HttpPost] 
public string Index(FormCollection fc, string searchString) 
{ 
    return "<h3> From [HttpPost]Index: " + searchString + "</h3>"; 
}

SearchPostGhost

No entanto, mesmo se você adicionar esta versão HttpPost do método Index, haverá uma limitação na forma de como isso tudo foi implementado. Imagine que você deseja adicionar uma pesquisa específica como Favoritos ou enviar um link para seus amigos para que eles possam clicar para ver a mesma lista filtrada de filmes. Observe que a URL da solicitação HTTP POST é a mesma que a URL para a solicitação GET (localhost:xxxxx/Movies/Index) – não há nenhuma informação de pesquisa na URL em si. No momento, as informações da cadeia de caracteres de pesquisa são enviadas ao servidor como um valor de campo de formulário. Isso significa que você não pode capturar essas informações de pesquisa para marcar ou enviar para amigos em uma URL.

A solução é usar uma sobrecarga de BeginForm que especifica que a solicitação POST deve adicionar as informações de pesquisa à URL e que ela deve ser roteada para a HttpGet versão do Index método. Substitua o método sem BeginForm parâmetros existente pela seguinte marcação:

@using (Html.BeginForm("Index","Movies",FormMethod.Get))

BeginFormPost_SM

Agora, quando você envia uma pesquisa, a URL contém uma cadeia de caracteres de consulta de pesquisa. A pesquisa também irá para o método de ação HttpGet Index, mesmo se você tiver um método HttpPost Index.

IndexWithGetURL

Adicionando Pesquisa por Gênero

Se você adicionou a HttpPost versão do método , exclua-a Index agora.

Em seguida, você adicionará um recurso para permitir que os usuários pesquisem filmes por gênero. Substitua o método Index pelo seguinte código:

public ActionResult Index(string movieGenre, string searchString)
{
    var GenreLst = new List<string>();

    var GenreQry = from d in db.Movies
                   orderby d.Genre
                   select d.Genre;

    GenreLst.AddRange(GenreQry.Distinct());
    ViewBag.movieGenre = new SelectList(GenreLst);

    var movies = from m in db.Movies
                 select m;

    if (!String.IsNullOrEmpty(searchString))
    {
        movies = movies.Where(s => s.Title.Contains(searchString));
    }

    if (!string.IsNullOrEmpty(movieGenre))
    {
        movies = movies.Where(x => x.Genre == movieGenre);
    }

    return View(movies);
}

Esta versão do Index método usa um parâmetro adicional, ou movieGenreseja, . As primeiras linhas de código criam um List objeto para conter gêneros de filme do banco de dados.

O código a seguir é uma consulta LINQ que recupera todos os gêneros do banco de dados.

var GenreQry = from d in db.Movies 
                   orderby d.Genre 
                   select d.Genre;

O código usa o AddRange método da coleção genérica List para adicionar todos os gêneros distintos à lista. (Sem o Distinct modificador, gêneros duplicados seriam adicionados — por exemplo, comédia seria adicionada duas vezes em nossa amostra). Em seguida, o código armazena a lista de gêneros no ViewBag.MovieGenre objeto . Armazenar dados de categoria (gêneros de filme) como um objeto SelectList em um ViewBag, acessar os dados de categoria em uma caixa de listagem suspensa é uma abordagem típica para aplicativos MVC.

O código a seguir mostra como marcar o movieGenre parâmetro . Se não estiver vazio, o código restringirá ainda mais a consulta de filmes para limitar os filmes selecionados ao gênero especificado.

if (!string.IsNullOrEmpty(movieGenre))
{
    movies = movies.Where(x => x.Genre == movieGenre);
}

Conforme mencionado anteriormente, a consulta não é executada no banco de dados até que a lista de filmes seja iterada (o que acontece no Modo de Exibição, após o retorno do método de ação Index ).

Adicionando marcação à exibição de índice para dar suporte à pesquisa por gênero

Adicione um Html.DropDownList auxiliar ao arquivo Views\Movies\Index.cshtml , pouco antes do TextBox auxiliar. A marcação concluída é mostrada abaixo:

@model IEnumerable<MvcMovie.Models.Movie>
@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
    @Html.ActionLink("Create New", "Create")
    @using (Html.BeginForm("Index", "Movies", FormMethod.Get))
    {
    <p>
        Genre: @Html.DropDownList("movieGenre", "All")
        Title: @Html.TextBox("SearchString")
        <input type="submit" value="Filter" />
    </p>
    }
</p>
<table class="table">

No seguinte código:

@Html.DropDownList("movieGenre", "All")

O parâmetro "MovieGenre" fornece a chave para o DropDownList auxiliar encontrar um IEnumerable<SelectListItem> no ViewBag. O ViewBag foi preenchido no método de ação:

public ActionResult Index(string movieGenre, string searchString)
{
    var GenreLst = new List<string>();

    var GenreQry = from d in db.Movies
                   orderby d.Genre
                   select d.Genre;

    GenreLst.AddRange(GenreQry.Distinct());
    ViewBag.movieGenre = new SelectList(GenreLst);

    var movies = from m in db.Movies
                 select m;

    if (!String.IsNullOrEmpty(searchString))
    {
        movies = movies.Where(s => s.Title.Contains(searchString));
    }

    if (!string.IsNullOrEmpty(movieGenre))
    {
        movies = movies.Where(x => x.Genre == movieGenre);
    }

    return View(movies);
}

O parâmetro "Todos" fornece um rótulo de opção. Se você inspecionar essa escolha no navegador, verá que o atributo "valor" dele está vazio. Como nosso controlador filtra apenas a cadeia de caracteres if não null está ou vazia, enviar um valor vazio para movieGenre mostra todos os gêneros.

Você também pode definir uma opção para ser selecionada por padrão. Se você quisesse "Comédia" como sua opção padrão, alteraria o código no Controlador da seguinte maneira:

ViewBag.movieGenre = new SelectList(GenreLst, "Comedy");

Execute o aplicativo e navegue até /Movies/Index. Experimente uma pesquisa por gênero, por nome de filme e por ambos os critérios.

Captura de tela que mostra a página Índice. Um tipo de gênero é selecionado.

Nesta seção, você criou um método de ação de pesquisa e exibição que permite que os usuários pesquisem por título e gênero de filme. Na próxima seção, você verá como adicionar uma propriedade ao Movie modelo e como adicionar um inicializador que criará automaticamente um banco de dados de teste.