Representación de vista parcial en el botón clic en ASP.NET MVC

El problema que describiré es muy similar a los que ya encontré (por ejemplo, esta publicación con un nombre casi idéntico ), pero espero poder convertirlo en algo que no sea un duplicado.

Creé una nueva aplicación ASP.NET MVC 5 en Visual Studio. Luego, definí dos clases de modelos:

public class SearchCriterionModel { public string Keyword { get; set; } } public class SearchResultModel { public int Id { get; set; } public string FirstName { get; set; } public string Surname { get; set; } } 

Luego creé el SearchController siguiente manera:

 public class SearchController : Controller { public ActionResult Index() { return View(); } public ActionResult DisplaySearchResults() { var model = new List { new SearchResultModel { Id=1, FirstName="Peter", Surname="Pan" }, new SearchResultModel { Id=2, FirstName="Jane", Surname="Doe" } }; return PartialView("SearchResults", model); } } 

así como las vistas Index.cshtml (fuertemente tipadas con SearchCriterionModel como modelo y plantilla Edit ) y SearchResults.cshtml como una vista parcial con modelo de tipo IEnumerable (template List ).

Esta es la vista de índice:

 @model WebApplication1.Models.SearchCriterionModel @{ ViewBag.Title = "Index"; } @using (Html.BeginForm()) { @Html.AntiForgeryToken() 

SearchCriterionModel


@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.Keyword, htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.Keyword, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Keyword, "", new { @class = "text-danger" })
}
@Html.ActionLink("Back to List", "Index")

Como puede ver, agregué un div con id="searchResults" debajo de la plantilla estándar y edité el botón. Lo que quiero es mostrar la vista parcial SearchResults.cshtml en el div en la parte inferior, pero solo después de hacer clic en el botón. He logrado mostrar una vista parcial allí usando @Html.Partial("SearchResults", ViewBag.MyData) , pero se representa cuando la vista principal se carga por primera vez y configuro ViewBag.MyData en el Index() método ya, que no es lo que quiero.

Resumen: al hacer clic en el botón, SearchResultModel algunas instancias de la List de ejemplos de SearchResultModel (a través del acceso a la base de datos) y luego la vista parcial se debe representar, utilizando los datos recién obtenidos como modelo. ¿Cómo puedo lograr esto? Ya me parece que fallas en el primer paso, que está reactjsndo al clic del botón con el código anterior. En este momento, ~/Search/DisplaySearchResults a la URL ~/Search/DisplaySearchResults , pero por supuesto no hay nada allí y no se llama a ningún método de código subyacente. En ASP.NET tradicional, acababa de agregar un controlador OnClick lado del servidor, configurar el DataSource para una grilla y mostrar la grilla. Pero en MVC ya fallo con esta simple tarea …

Actualización: Cambiando el botón a @Html.ActionLink Finalmente puedo ingresar el método del controlador. Pero, naturalmente, dado que devuelve la vista parcial, se muestra como el contenido de la página completa. Entonces, la pregunta es: ¿cómo digo que la vista parcial se represente dentro de un div específico en el lado del cliente?

Cambiar el botón a

  

y agregue la siguiente secuencia de comandos

 var url = '@Url.Action("DisplaySearchResults", "Search")'; $('#search').click(function() { var keyWord = $('#Keyword').val(); $('#searchResults').load(url, { searchText: keyWord }); }) 

y modificar el método del controlador para aceptar el texto de búsqueda

 public ActionResult DisplaySearchResults(string searchText) { var model = // build list based on parameter searchText return PartialView("SearchResults", model); } 

El método jQuery .load llama a su método de controlador, pasando el valor del texto de búsqueda y actualiza el contenido de

con la vista parcial.

Nota al @Html.ValidationSummary() : el uso de una etiqueta

y @Html.ValidationSummary() y @Html.ValidationMessageFor() probablemente no sean necesarios aquí. Nunca devuelve la vista de Index para que ValidationSummary no tenga sentido y supongo que desea que un texto de búsqueda null devuelva todos los resultados y, en cualquier caso, no tiene ningún atributo de validación para la propiedad Keyword por lo que no hay nada que validar.

Editar

Según los comentarios de OP que SearchCriterionModel contendrá múltiples propiedades con atributos de validación, el enfoque sería incluir un botón de envío y manejar los formularios .submit() event

  var url = '@Url.Action("DisplaySearchResults", "Search")'; $('form').submit(function() { if (!$(this).valid()) { return false; // prevent the ajax call if validation errors } var form = $(this).serialize(); $('#searchResults').load(url, form); return false; // prevent the default submit action }) 

y el método del controlador sería

 public ActionResult DisplaySearchResults(SearchCriterionModel criteria) { var model = // build list based on the properties of criteria return PartialView("SearchResults", model); }