Problem
When sorting and paging are not enough to help users find the results they want, another way to help users find the results they want is to filter according to special rules.
Solution
New links can be added to allow filtering by conditions in advance and the data is filtered by using the LINQ class library.
Discussion
To add filtered links, you need to change the link in Book/Index view and BookController.
The changed View is similar to the first two recipes. You need to add HTML to allow users to select how they want to filter the content. Three connections will be added: All, newly released, and coming soon. New releases will be defined as those released in the last two weeks. The coming version is defined as not released yet.
Next is the new Book/Index view. There are three links. The first link contains the current sortOrder, and the remaining two links contain the new variable filter. Like paging link. If the current filter is selected, it will be displayed as static text rather than link, and other fitler will be set as link. Make sure that the filter is maintained when you change the sorting rule. Our Index view should be updated as follows:
@ Html. Partial ("_ Paging ")
<Table>
<Tr>
<Th>
@ Html. ActionLink ("Title", "Index", new
{
SortOrder = ViewBag. TitleSortParam,
Filter = ViewBag. CurrentFilter
})
</Th>
<Th>
@ Html. ActionLink ("Isbn", "Index", new
{
SortOrder = ViewBag. IsbnSortParam,
Filter = ViewBag. CurrentFilter
})
</Th>
<Th>
Summary
</Th>
<Th>
@ Html. ActionLink ("Author", "Index", new
{
SortOrder = ViewBag. AuthorSortParam,
Filter = ViewBag. CurrentFilter
})
</Th>
<Th>
Thumbnail
</Th>
<Th>
@ Html. ActionLink ("Price", "Index", new
{
SortOrder = ViewBag. PriceSortParam,
Filter = ViewBag. CurrentFilter
})
</Th>
<Th>
@ Html. ActionLink ("Published", "Index", new
{
SortOrder = ViewBag. PublishedSortParam,
Filter = ViewBag. CurrentFilter
})
</Th>
<Th>
</Th>
</Tr>
@ Foreach (var item in Model)
{
<Tr>
<Td>
@ Html. DisplayFor (modelItem => item. Title)
</Td>
<Td>
@ Html. DisplayFor (modelItem => item. Isbn)
</Td>
<Td>
@ Html. DisplayFor (modelItem => item. Summary)
</Td>
<Td>
@ Html. DisplayFor (modelItem => item. Author)
</Td>
<Td>
@ Html. DisplayFor (modelItem => item. Thumbnail)
</Td>
<Td>
@ Html. DisplayFor (modelItem => item. Price)
</Td>
<Td>
@ Html. DisplayFor (modelItem => item. Published)
</Td>
<Td>
@ Html. ActionLink ("Edit", "Edit", new {id = item. ID}) |
@ Html. ActionLink ("Details", "Details", new {id = item. ID}) |
@ Html. ActionLink ("Delete", "Delete", new {id = item. ID })
</Td>
</Tr>
}
</Table>
@ Html. Partial ("_ Paging ")
The _ Paging Partial view created in the previous secret recipe also needs to be updated. In the following example, four paging links have been updated to pass the current filter, page, and sortOrder. The following is the updated code of _ Paging:
<P>
@ If (Model. HasPreviousPage)
{
@ Html. ActionLink ("<First", "Index", new
{
Page = 1,
SortOrder = ViewBag. CurrentSortOrder,
Filter = ViewBag. CurrentFilter
})
@ Html. Raw ("& nbsp ;");
@ Html. ActionLink ("<Prev", "Index", new
{
Page = Model. PageNumber-1,
SortOrder = ViewBag. CurrentSortOrder,
Filter = ViewBag. CurrentFilter
})
}
Else
{
@: <First
@ Html. Raw ("& nbsp ;");
@: <Prev
}
& Nbsp;
@ If (Model. HasNextPage)
{
@ Html. ActionLink ("Next>", "Index", new
{
Page = Model. PageNumber + 1,
SortOrder = ViewBag. CurrentSortOrder,
Filter = ViewBag. CurrentFilter
})
@ Html. Raw ("& nbsp ;");
@ Html. ActionLink ("Last>", "Index", new
{
Page = Model. PageCount,
SortOrder = ViewBag. CurrentSortOrder,
Filter = ViewBag. CurrentFilter
})
}
Else
{
@: Next>
@ Html. Raw ("& nbsp ;")
@: Last>
}
</P>
Next we will change the BooksController and change the code in Index () Action. Receives a new filter variable. The list of books will be reduced based on the selected filter options. In method 2, filter is implemented.
• Use the where clause of the dynamic Linq library again. Www.2cto.com
• Use standard Linq and a switch block to create a strongly typed clause.
Because the traditional filter link does not contain too many entries, we choose the second method. The advantage of doing so is that we do not need to consider the problem of SQL injection, because it is strongly typed and not dynamic.
Some codes of BooksController are as follows:
Using System;
Using System. Collections. Generic;
Using System. Data;
Using System. Data. Entity;
Using System. Linq;
Using System. Linq. Dynamic;
Using System. Web;
Using System. Web. Mvc;
Using MvcApplication. Models;
Using MvcApplication. Utils;
Using PagedList;
Namespace MvcApplication. Controllers
{
Public class BooksController: Controller
{
Private BookDBContext db = new BookDBContext ();
//
// GET:/Books/
Public ViewResult Index (string sortOrder, string filter, int page = 1)
{
# Region ViewBag Resources
# Endregion
# Region ViewBag Sort Params
# Endregion
Var books = from B in db. Books select B;
# Region Filter Switch
Switch (filter)
{
Case "NewReleases ":
Var startDate = DateTime. Today. AddDays (-14 );
Books = books. Where (B => B. Published
<= DateTime. Today. Date
& Amp; B. Published & gt; = startDate
);
Break;
Case "ComingSoon ":
Books = books. Where (B => B. Published>
DateTime. Today. Date );
Break;
Default:
// No filter needed
Break;
}
ViewBag. CurrentFilter =
String. IsNullOrEmpty (filter )? "": Filter;
# Endregion
Books = books. OrderBy (sortOrder );
Const int maxRecords = 2;
Var currentPage = page <= 0? 1: page;
Return View (books. ToPagedList (currentPage, maxRecords ));
}
}
}
In the above example, if you select the NewReleases filter, the search will return the book published today or within 14 days. Alternatively, if you select Coming soon, the search will return the book to be published.
Author technical brother