问题
In a single ASP.NET Razor view, I want to display 10 textboxes (the user will enter various search criteria into these), and then when the user submits the form and the server processes the action, I want to display the results in the same view (let's assume that there can be around a 1,000 rows that need to be displayed). Along with the results, I also want criteria textboxes populated with the values that the user had chosen previously (so that the user can modify the criteria if required and then click Submit again).
How do I pass the various data back and forth?
Option 1 - create a single view model class, that has 10 properties (one for each criteria), and a 11th property (a List) that holds the results. As far as I understand, the values in the model will be passed back to the server when the user clicks Submit (that's how the server gets the criteria values). Does this mean that all the 1,000 rows are also passed back?
Option 2 - create a view model class that holds the 10 properties. Use ViewBag for passing the List that holds the results. Thus, only the criteria data is sent back when the user clicks Submit a 2nd item, while the displayed rows aren't sent back to the server (since they weren't stored in the model).
Are there other approaches? Which approach should I use?
回答1:
Go with Option 1: I don't see any reason to use ViewBag in this scenario. Just pass the model to the view in your controller action method.
return View(model);
You'd have two action methods, both returning same view. One method for when you first visit the page:
[HttpGet]
public ActionResult Query()
{
return View(new FormQueryModel())
}
...and another one for when user submits search criteria. This runs the query and pass a model populated with results for the view to display them.
[HttpPost]
public ActionResult Query(FormQueryModel model)
{
var queryManager = new QueryManager(model);
model.QueryResults = queryManager.GetResults();
return View(model);
}
And no, you don't have to post back the results from a previous search to the controller again. In my case I just leave results outside the form tag so it's not posted back. But as long you don't bind the result, you'd be okay.
@model FormQueryModel
@using (Html.BeginForm("Query", "Home"))
{
@Html.LabelFor(m => m.Age)
@Html.TextBoxFor(m => m.Age)
@Html.LabelFor(m => m.Country)
@Html.TextBoxFor(m => m.Country)
}
@if (Model.QueryResults.Count > 0)
{
@foreach (var result in Model.QueryResults)
{
//display results here
}
}
Also you need to add some pagination as the user is not going to read 1000 rows. If the search is returning too many rows user would add more filter conditions instead.
public class FormQueryModel
{
public int PageSize { get; set; }
[Display(Name = "Enter your age")]
public int Age { get; set; }
[Display(Name = "Enter your country")]
public string Country { get; set; }
public List<QueryResult> QueryResults { get; set; }
public FormQueryModel()
{
this.QueryResults = new List<QueryResult>();
}
}
来源:https://stackoverflow.com/questions/48250715/asp-net-mvc-taking-search-criteria-as-input-and-displaying-the-results-in-th