§ 4. 7 grouping a custom URL schema
How is the MVC framework supposed to invoke your list () method when it doesn't know whatValue to supplyFor page?Change the URLIn your browser to http: // localhost: XXXXX /? Page = 1 or http: // localhost: XXXXX /? Page = 2. You'll find that it works, and your application will select and display the relevant page of results.
§ 4. 7.1 assigning a default parameter value
It's very easy to tell ASP. net mvc what value to use for an action method parameter if no other value is \ available. Update productscontroller's list () method signature by applying[Defaultvalue] attribute:
Public viewresult list ([defaultvalue (1)] int page) {return view (productsrepository. products. tolist (). skip (page-1) * pagesize ). take (pagesize ). tolist ());}
§ 4. 7.2 displaying page links
We're re going to pass information about the number of pages, the current page index, and so on to the HTML helper using a small model class calledPaginginfo. Add the following class to yourSportsstore. webuiProject's models Folder:
Namespace sportsstore. models {public class paginginfo {public int totalitems {Get; set;} public int itemsperpage {Get; set;} public int currentpage {Get; set ;} public int totalpages {get {return (INT) math. ceiling (decimal) totalitems/itemsperpage );}}}}
This isn' tDomain Model. We call these simple objects are sometimes calledData transfer objects (dtos ),
Now we can implement the pagelinks HTML helper method. Create a new folder in yourSportsstore. webuiProject calledHtmlhelpers, And then add a new static class calledPaginghelpers.
namespace sportsstore. htmlhelpers {public static class paginghelpers {public static mvchtmlstring pagelinks (this htmlhelper HTML, paginginfo, func
pageurl) {stringbuilder result = new stringbuilder (); for (INT I = 1; I <= paginginfo. totalpages; I ++) {tagbuilder tag = new tagbuilder ("A"); // construct an
tag. mergeattribute ("href", pageurl (I); tag. innerhtml = I. tostring (); if (I = paginginfo. currentpage) Tag. addcssclass ("selected"); result. appendline (tag. tostring ();} return mvchtmlstring. create (result. tostring () ;}}
Then we add something into the list. aspx as follows:
<% = Html. pagelinks (New paginginfo {currentpage = 2, totalitems = 28, itemsperpage = 10}, I => URL. action ("list", new {page = I}) %>
§ 4. 7.3 making the HTML helper method visible to all view pages
Rather than copying and pasting that same Declaration to all aspx views that usePagelinks(), How about registeringSportsstore. webui. htmlhelpersNamespaceGlobally? OpenWeb. configAnd findNamespaces NodeInside system. Web/pages. Add your HTML helper namespace to the bottom of the list:
<Namespaces> <add namespace = "system. web. MVC "/> <add namespace =" system. web. MVC. ajax "/>... etc... <add namespace = "sportsstore. webui. htmlhelpers "/> </namespaces>
§ 4. 7.4 supplying a page number to the view
Because you don't know how many pages there are and what page number it's displaying. So, you need to enhanceControllerTo put that extra informationViewdata. Model.
Maybe you will use viewdata as a dictionary which we talked before. But it is loosely typed. So here we add the following class to yourSportsstore. webuiProject'sModelsFolder to encapsulate all the data that list needs to send to its view
Namespace sportsstore. webui. Models {public class productslistviewmodel {public ilist <product> Products {Get; Set ;} public paginginfo {Get; Set ;}}}
Now you can update the list () method to supply a productslistviewmodel to its view:
Public viewresult list ([defaultvalue (1)] int page) {var productstoshow = productsrepository. products; var viewmodel = new productslistviewmodel () {products = productstoshow. skip (page-1) * pagesize ). take (pagesize ). tolist (), paginginfo = new paginginfo {currentpage = page, itemsperpage = pagesize, totalitems = productstoshow. count () }}; return view (viewmodel );}
Also, you need remember we must change the reciever's module type:
<% @ Page title = "" Language = "C #" masterpagefile = "~ /Views/shared/site. Master "inherits =" viewpage <sportsstore. webui. Models. productslistviewmodel> "%>
And the rest of that view:
<% Foreach (VAR product in model. products) {%> <Div class = "item">
§ 4. 7.5 Improving the URLs
Currently, sportsstore uses quite strange URLs, such /? Page = 2, for browsing the pages of a product listing. I 'd prefer that URL simply to be/page2
So switch overGlobal. asax. CS
Public static void registerroutes (routecollection routes) {routes. ignoreroute ("{resource }. axd/{* pathinfo} "); routes. maproute (null, // route name "Page {page}", // URL with parameters new {controller = "Products ", action = "list"} // parameter defaults );}
Then you can run it
§ 4. 8 styling it up
In terms of ASP. NET master pages and content pages, the header and Sidebar will be defined in the master page, while the main body will be a contentplaceholder calledMaincontent
§ 4. 8.1 defining page layout in the master page
You can easily achieve this layout by updating your master page template,/Views/shared/site. MasterAs follows:
<% @ Master language = "C #" inherits = "system. Web. MVC. viewmasterpage" %> <! Doctype HTML public "-// W3C // dtd xhtml 1.0 transitional // en" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <HTML xmlns = "http://www.w3.org/1999/xhtml">
§ 4. 8.2 adding CSS rules
now change the default CSS /content/site.css , the added part as follows:
/* -- Leave rest as is -- */body {font-family: Cambria, Georgia, "Times New Roman"; margin: 0;} Div # header Div. title, Div. item H3, Div. item H4, Div. pager A {Font: bold 1em "Arial narrow", "Franklin Gothic Medium", Arial;} Div # header {background-color: #444; border-bottom: 2px solid #111; color: White;} Div # header Div. title {font-size: 2em; padding :. 6em;} Div # Content {border-left: 2px solid gray; margin-left: 9em; padding: 1em;} Div # categories {float: Left; width: 8em; padding :. 3em;} Div. item {border-top: 1px dotted gray; padding-top :. 7em; margin-bottom :. 7em;} Div. item: First-child {border-top: none; padding-top: 0;} Div. item H3 {font-size: 1.3em; margin: 0 0. 25em 0;} Div. item H4 {font-size: 1.1em; margin :. 4em 0 0 0;} Div. pager {text-align: Right; border-top: 2px solid silver; padding :. 5em 0 0 0; margin-top: 1em;} Div. pager A {font-size: 1.1em; color: #666; text-Decoration: none; padding: 0. 4em 0. 4em;} Div. pager A: hover {background-color: Silver;} Div. pager. selected {background-color: #353535; color: White;} 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;} FORM {margin: 0; padding: 0;} Div. item FORM {float: Right;} Div. item input {color: White; Background-color: #333; Border: 1px solid black; cursor: pointer;} H2 {margin-top: 0.3em} tfoot TD {border-top: 1px dotted gray; font-weight: bold ;}. actionbuttons A {Font :. 8em Arial; color: White; margin: 0. 5em 0. 5em; text-Decoration: none; padding :. 15em 1.5em. 2em 1.5em; Background-color: #353535; Border: 1px solid black;} Div # cart {float: Right; margin :. 8 em; color: Silver; Background-color: #555; padding :. 5em. 5em. 5em 1em;} Div # cart a {text-Decoration: none; padding :. 4em 1em. 4em 1em; line-Height: 2.1em; margin-left :. 5em; Background-color: #333; color: White; Border: 1px solid black ;}
And linkSite.cssWithSite. Master
<Head runat = "server"> <title> <asp: contentplaceholder id = "titlecontent" runat = "server"/> </title> <LINK rel = stylesheet href = ".. /.. /content/site.css "/>
Now you can see the graphic design.
§ 4. 8.3 creating a partial view
In the end, let me show you another trick to simplifyList. aspx view.You'll now learn how to create Partial View.Create a partial view file~ /Views/shared/
And update the Code as follows:
<% @ Control Language = "C #" inherits = "system. web. MVC. viewusercontrol <sportsstore. domain. entities. product> "%> <Div class =" item ">
Also, you need to update/Views/products/list. aspxSo that it uses your new partial view, passingProductParameter that will become the partial view's model:
<Asp: Content ID = "content2" contentplaceholderid = "maincontent" runat = "server"> <% foreach (VAR product in model. products) {%> <% HTML. renderpartial ("productsummary", product); %><%}%> <Div class = "pager" ><%= HTML. pagelinks (model. paginginfo, x => URL. action ("list", new {page = x}) %> </div> </ASP: content>
Now you can run your application. And there is no change. That's a satisfying simplification.