Previously added the paging function for sportsstore. Then we add navigation control and use the menu on the left to classify and display data.
First, modify productslistviewmodel. CS under sportsstore. webui. Models and add the currentcategory attribute Public String currentcategory {Get; set ;}.
Then, modify the List action method to filter the list of queried products through the input currentcategory. The modified List action method is as follows:
public ViewResult List(string category, int page = 1) {
ProductsListViewModel viewModel = new ProductsListViewModel
{
Products = repository.Products.Where(p => category == null || p.Category == category)
.OrderBy(p => p.ProductID)
.Skip((page - 1) * PageSize)
.Take(PageSize),
PagingInfo = new PagingInfo
{
CurrentPage = page,
ItemsPerPage = PageSize,
TotalItems = category == null ? repository.Products.Count() : repository.Products.Where(e => e.Category == category).Count()
}
};
return View(viewModel);
}
Through the. Where extension method, we perform a vertical filtering to filter the product of the specified category.
Redefinition of URL combinations
Previously we saw a URL like this /? Category = soccer. This is common in webform, but in MVC, it can be replaced in a more elegant way. Modify the registerroutes method in global. asax. CS. As follows:
Public static void registerroutes (routecollection routes)
{
Routes. ignoreroute ("{resource}. axd/{* pathinfo }");
Routes. maproute (null,
"", // Match an empty URL
New {controller = "product", Action = "list", Category = (string) null, page = 1}
);
Routes. maproute (null,
"Page {page }",
New {controller = "product", Action = "list", Category = (string) null },
New {page = @ "\ D +"} // constraint: The page must be a number.
);
Routes. maproute (null,
"{Category}", // match/football or/anythingwithnoslash
New {controller = "product", Action = "list", page = 1}
);
Routes. maproute (null,
"{Category}/Page {page}", // match/football/page567
New {controller = "product", Action = "list"}, // default
New {page = @ "\ D +"} // The value must be a number.
);
Routes. maproute (null,
"{Category}/Page {page}", // match/football/page567
New {controller = "product", Action = "list"}, // default
New {page = @ "\ D +"} // Constraints
);
Routes. maproute (
"Default", // route name
"{Controller}/{action}/{ID}", // URL with Parameters
New {controller = "product", Action = "list", id = urlparameter. optional} // default value of the Parameter
);
}
The preceding concentrated combination represents the combination of the following concentrated urls:
ASP. net Routing System (Routing System) is used by MVC to process requests from the client, but also requests to output URLs that conform to our URL combination, and the URL that can be embedded in Web pages. This ensures that the URL remains unchanged in our program. The following sections describe routing in detail, so it doesn't matter if we don't understand it here.
The URL. Action method is the most convenient way to create an outgoing links. It has been used in list. cshtml. We need to add support for category filtering and pass data to the helper method. As follows:
@model SportsStore.WebUI.Models.ProductsListViewModel
@{
ViewBag.Title = "Products";
}
Product List@foreach (var p in Model.Products)
{
@* <div class="item">
@p.Description
</div> *@
Html.RenderPartial("ProductSummary", p);
}
<div class="pager">
@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new { page = x, category = Model.CurrentCategory }))
</div>
The pagination link is in the form of http: // <myserver >:< port>/page2. This indicates that the page 2nd in all products is displayed. Http: // <myserver >:< port>/Chess/page2 this will only display the product whose category is chess.
Bind a category navigation menu
We need to display a navigation menu selected by all users, and then display the corresponding product list. In addition, we will use the category list in multiple controllers. Therefore, we need an independent and reusable category list. In the ASP. net mvc Framework, the sub-action (Child actions) concept is introduced, which is very suitable for creating a reusable navigation control menu. Child actions requires the HTML-assisted method renderaction, which allows us to include the output of an action method corresponding to the view. Here, we can create a new Controller: navcontroller and a menu Action Method to present a navigation menu and inject the output from the action method into layout.
Add navcontroller as follows:
Public class navcontroller: Controller
{
Private iproductsrepository repository;
Public navcontroller (iproductsrepository repo)
{
Repository = repo;
}
Public partialviewresult menu (string Category = NULL)
{
Viewbag. selectedcategory = category; // The viewbag used here transmits the selected category to the view.
Ienumerable <string> categories = repository. Products
. Select (x => X. Category)
. Distinct ()
. Orderby (x => X );
Return partialview (categories );
}
}
To use this navigation menu on all pages, you need to inject it into _ layout. The modified _ layout is as follows:
<!DOCTYPE html>
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<body>
<div id="header">
<div class="title">
Sports Store</div>
</div>
<div id="categories">
@{Html.RenderAction("Menu", "Nav");}
</div>
<div id="content">
@RenderBody()
</div>
</body>
Note: Like renderaction (), renderpartial () directly writes content to the response stream.
That is to say, the return value is void, so you cannot use the "@" label in razor, but include it in a closed block such.
If you do not like this, you can use the action method instead.
Next, add the menu view and right-click the menu controller to add the view. Note: The view here is a partial view, similar to the customer control in webform:
@model IEnumerable<string>
@{
Layout = null;
}
@Html.ActionLink("Home", "List", "Product")
@foreach (var link in Model)
{
@Html.RouteLink(link, new { controller = "Product", action = "List", category = link, page = 1 },
new { @class = link == ViewBag.SelectedCategory ? "selected" : null })
}
Add a style as follows:
View code
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 A.selected { background-color: #666; color: White; }
DIV#categories A:hover { background-color: #CCC; }
DIV#categories A.selected:hover { background-color: #666; }
In the menu view, there is such a @ Classe usage. We use @ class as a new parameter in the anonymous object and pass it to the routelink method. The "@" here is not a razor tag. We use a function in C, by adding a @ conformity to the class, you can avoid conflicts between the class defined in HTML and the key class defined in C. If @ compliance is not added here, a class is defined by the C # compiler. After @ compliance is added, the compilation will know that we are adding a parameter named class in the anonymous type. This is exactly what we expect.
Today's note is here. A simple shopping cart will be created later. In general, this project instance mainly enables us to have a practical understanding of MVC. Some specific implementations of the project are as follows, for example, all pages are read by page. This may not meet the actual requirements, but it is not important. It is important to have an overall understanding of MVC through this instance, and to have some experience in the development of practical projects in the future through specific operations. If you are following my notes, please leave a message! I wrote my notes after I did it myself, so I will choose to discard some of the steps in the middle.
Good night!