§ 5. 1.1 filtering the product list
Start the implementation by adding a new parameter, category,Productscontroller's list ()
Public viewresult list (string category, [defaultvalue (1)] int page)
And add a new string property calledCurrentcategoryToProductslistviewmodel:
Namespace sportsstore. webui. models {public class productslistviewmodel {public ilist <product> Products {Get; set;} public paginginfo {Get; set;} Public String currentcategory {Get; Set ;}}}
§ 5. 1.2 Implementing the category Filter
To implement the filtering behavior, updateProductscontroller's list ()Method as follows:
Public viewresult list (string category, [defaultvalue (1)] int page) {var productstoshow = (Category = NULL )? Productsrepository. products: productsrepository. products. where (x => X. category = category); var viewmodel = new productslistviewmodel () {products = productstoshow. skip (page-1) * pagesize ). take (pagesize ). tolist (), paginginfo = new paginginfo {currentpage = page, itemsperpage = pagesize, totalitems = productstoshow. count ()}, currentcategory = Category}; return view (viewmodel) ;}
Also, we need to updateGlobal. aspxFile because of the routing.
Public static void registerroutes (routecollection routes) {routes. ignoreroute ("{resource }. axd/{* pathinfo} "); routes. maproute (null, // route name "{category} // URL with parameters new {controller =" Products ", Action =" list "}/parameter defaults );}
In this way, run the application as follows:
Maybe you noticed that this title is different. Yeah, let's change it inSite. Master:
<Div id = "Header"> <Div class = "title"> <asp: contentplaceholder id = "titlecontent" runat = "server"/> </div>
AndList. aspxWith:
<Asp: Content ID = "content1" contentplaceholderid = "titlecontent" runat = "server"> sportsstore: <% = model. currentcategory ?? "All products" %> </ASP: content>
§ 5. 1.3 defining a URL schema for categories
implement the desired URL schema by replacing your existing registerroutes () method (in global. asax. CS ) with the following:
Public static void registerroutes (routecollection routes) {routes. ignoreroute ("{resource }. axd/{* pathinfo} "); routes. maproute (null, "", // only matches the empty URL (I. e. ~ /) New {controller = "Products", Action = "list", Category = (string) null, page = 1}); routes. maproute (null, "page {page}", // matches ~ /Page2 ,~ /Page123, but not ~ /Pagexyz new {controller = "Products", Action = "list", Category = (string) null}, new {page = @ "\ D +"} // constraints: page must be numerical); routes. maproute (null, // route name "{category}", // URL with parameters new {controller = "Products", Action = "list ", page = 1} // parameter defaults); routes. maproute (null, "{category}/Page {page}", new {controller = "Products", Action = "list "}, // defaults new {page = @ "\ D +"} // constraints: page must be numerical); routes. maproute (null, "{controller}/{action }");}
The golden rule is to put more-specific routes first, so that they're always chosen in preference to less-specific ones.
And we need to updateList. aspx'S call to HTML.Pagelinks():
<Div class = "pager"> <% = html. pagelinks (model. paginginfo, x => URL. action ("list", new {page = x, catetory = model. currentcategory}) %> </div>
Now that you 've done all this, you'll find that if you visit a URL such/Chess
§ 5. 1.4 building a category navigation menu
Building a category navigation menu
Get started by creating a new controller class,Navcontroller,I will fullfill thecode later.
Selecting and rendering a list of Category links
First, let's create a new class to describe a link that cocould be rendered in the navigation menu. Add the following to your models Folder:
Namespace sportsstore. webui. Models {public class navlink {Public String text {Get; set;} public routevaluedictionary routevalues {Get; set;} public bool isselected {Get; Set ;}}}
And updateNavcontrollerSo that it produces an appropriate list of category data
Namespace sportsstore. webui. controllers {public class navcontroller: controller {private iproductsrepository productsrepository; Public navcontroller (iproductsrepository productsrepository) {This. productsrepository = productsrepository;} public viewresult menu (string category) {func <string, navlink> makelink = categoryname => New navlink {text = categoryname ?? "Home", routevalues = new system. Web. Routing. routevaluedictionary (New {controller = "Products", Action = "list", Category = categoryname = NULL? Null: categoryname. trim (), page = 1}), isselected = (categoryname = Category)}; List <navlink> navlinks = new list <navlink> (); navlinks. add (makelink (null); // Add a link for each distinct category var categories = productsrepository. products. select (x => X. category); foreach (string categoryname in categories. distinct (). orderby (x => X) navlinks. add (makelink (categoryname); Return view (navlinks );}}}
Of course, after the controller. We needView
Since this navigation widget is supposed to be just a fragment of a page, not an entire page in its own right, it makes sense for its view to beA partial viewRather than regular view.
Previusly you 've only renderedPartial viewsBy callingHtml. renderpartial (),But as you'll see, it's just as easy to tell any action method to render a partial view. This is mainly beneficial if you're usingHtml. renderaction ()Or if you're usingAjax(See chapter 14 ).
To make a nice view, we also need to adding a few CSS rules/Content/site.css
Div # categories A {Font: bold 1.1em "Arial narrow", "Franklin Gothic Medium", Arial; display: block; text-Decoration: none; padding :. 6em; color: black; border-bottom: 1px solid silver;} Div # categories. selected {background-color: #666; color: White;} Div # categories A: hover {background-color: # CCC;} Div # categories. selected: hover {background-color: #666 ;}