新建 ASP.NET MVC 项目快速代码
视图模型- PagingInfo 类:
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); } }
}
创建 “HtmlHelpers” 文件夹,在 PagingHelper 类中定义 HTML 辅助器方法 PageLinks:
public static class PagingHelpers
{
/// <summary>
/// HTML 的扩展方法,用来生成页面链接
/// </summary>
/// <param name="html">第一个参数带“this”,表示这是一个扩展方法</param>
/// <param name="pagingInfo">所需的分页信息</param>
/// <param name="pageUrl">第3个参数是一个方法,该方法的输入参数是int类型(这里是页码),返回string类型(这里是输出URL)</param>
/// <returns></returns>
public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfo pagingInfo, Func<int, string> pageUrl)
{
StringBuilder result = new StringBuilder();
for (int i = ; i <= pagingInfo.TotalPages; i++)
{
TagBuilder tag = new TagBuilder("a"); //添加一个<a>标签
tag.MergeAttribute("href", pageUrl(i)); //标签所指向的页数,第二个参数是一个方法,而方法的参数是当前的i
tag.InnerHtml = i.ToString(); //标签显示的文本
if (i == pagingInfo.CurrentPage)
{
tag.AddCssClass("selected"); //对当前页的<a>标签添加值为selected的class属性
tag.AddCssClass("btn-primary");
}
tag.AddCssClass("btn btn-default"); //对所有的<a>标签都添加值为“默认按钮”的class属性
result.Append(tag.ToString());
}
return MvcHtmlString.Create(result.ToString());
}
}
生成页面链接的 Html.PageLinks 方法
需要引入视图模型所在的命名空间
为更好的向视图传递数据,更好的做法是将控制器发送给视图的所有数据封装成一个单一的视图模型:
public class UserListViewModel
{
public IEnumerable<t_user> Users { get; set; } //页面显示需要的数据
public PagingInfo PagingInfo { get; set; } //分页信息
public string CurrentCategory { get; set; } //当前分类
}
在视图中添加的显示分页链接的代码:
<div>
@Html.PageLinks(Model.PagingInfo, x => Url.Action("动作方法名", new { page = x, category = Model.CurrentCategory }))
<!-- 该扩展方法的第二个参数传递的是一个方法,该方法指明了在扩展方法的某一步中要实现什么功能,而且就像普通参数一样可以在循环中被重复使用 -->
<!-- 具体的是:在一个循环中,当当前值小于所需要的页面总数时,传入当前要生成的链接对应的页码(int 类型),生成对应的链接(包含了页码和分类) -->
<!-- 如果每次视图模型都带有 PagingInfo 属性,则方法中的第一个实参 “Model.PagingInfo” 就总是不用改变,而对于链接所生成的具体信息,全在于后面的动作方法名以及匿名对象中的属性名和对应的值 -->
<!-- new 的是一个路由值对象,可以填充路由设置中对应的部分 -->
</div>
带有分页和并根据所选分类进行过滤的(Product)控制器:
public class ProductController : Controller
{
private IProductsRepository repository; //用于……
public int PageSize = ; //分页中每页显示的项目数 public ProductController(IProductsRepository productRepository) //通过初始化器声明依赖项
{
this.repository = productRepository;
} public ViewResult List(string category,int page=)
{
ProductsListViewModel model = new ProductsListViewModel {
Products= repository.Products.Where(p=>category==null||p.Category==category).OrderBy(p => p.id).Skip((page - ) * PageSize).Take(PageSize),
PagingInfo=new PagingInfo {
CurrentPage = page,
ItemsPerPage = PageSize,
TotalItems = category == null ? repository.Products.Count() : repository.Products.Where(e=>e.Category==category).Count() //将分类考虑进分页信息
},
CurrentCategory = category
};
return View(model);
}
} 使用 SQLSuger 的简单类似实现:
public ActionResult GetComStaffs(int page=1)
{
UserListViewModel result = new UserListViewModel();
using (var db = new SqlSugarClient(DBHelper.connectionString))
{
var lusers = db.Queryable<t_user>().Where(u => u.Isdel == false).ToList(); //db.Queryable<t_user>().Where(u => u.Isdel == false).OrderBy(u=>u.id).ToPageList(page, 10);
result.Users = lusers.Skip((page - 1) * 10).Take(10);
result.PagingInfo = new PagingInfo { CurrentPage = page, TotalItems = lusers.Count,ItemsPerPage=10 };
}
return View(result);
}
调整 URL 方案 —— 修改 App_Start / RouteConfig.cs 文件中的 RegisterRoutes 方法:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//重点看第二个参数(这个参数对应着实际的链接的形式),后面的匿名类型对象对应着当出现这种情况时自动补齐的值
routes.MapRoute(null, "", new { controller = "Product", action = "List", category = (string)null, page = }); routes.MapRoute(null, "Page{page}", new { controller = "Product", action = "List", category = (string)null }, new { page = @"\d+" }); routes.MapRoute(null, "{category}", new { controller = "Product", action = "List", page= }); routes.MapRoute(null, "{category}/Page{page}", new { controller = "Product", action = "List" }, new { page = @"\d+" }); routes.MapRoute(null, "{controller}/{action}");
}
}
生成分类列表(定义 “Nav” 控制器和 “Menu” 方法):
public class NavController : Controller
{
private IProductsRepository repository; public NavController(IProductsRepository repo) //构造器
{
repository = repo;
} public PartialViewResult Menu(string category=null)
{
//这里是处于多样性的目的,更常规的做法是床架一个视图模型,它含有分类列表和所选分类
ViewBag.selectedCategory = category; //将选择的分类通过控制器的动作方法再传递给视图,用来 “高亮显示当前分类” IEnumerable<string> categories = repository.Products.Select(x => x.Category).Distinct().OrderBy(x => x);
return PartialView(categories); //返回一个分部视图(分类导航菜单确实也只是整个页面的一部分)
}
}
在 “分类导航菜单” 控制器中添加一个构造器,其参数接受的是 IProductRepository 的一个实现。(其效果是声明了一个由 Ninject 进行解析的依赖项,用以创建这个 NavController 类的实例)
在 “Menu” 动作方法中使用 LINQ 查询从存储库获取分类列表,并将它们传递给视图。(返回的是分部视图)
分类导航菜单对应的分部视图:
@model IEnumerable<string> <!-- 添加了一个叫做“Home”的链接,它将出现在分类列表的顶部,并在无分类过滤器作用的情况下列举所有产品。(这是用 ActionLink 辅助器方法来实现的) -->
@Html.ActionLink("Home","List","Product",null,new { @class = "btn btn-block btn-default btn-lg"})
<!-- 枚举分类名称,并用 RouteLink 方法为每个分类创建链接。—— 该辅助器方法与 ActionLink 类似,但在根据路由配置生成URL时,它让笔者能够有针对性地在匿名对象中提供一组“键/值”对,它们为路由的各个片段提供了数据 -->
@foreach (var link in Model)
{
@Html.RouteLink(link,new { controller= "Product",action="List",category=link,page= },new { @class = "btn btn-block btn-default btn-lg"
+ (link == ViewBag.selectedCategory ? " btn-primary" : "") }) //如果当前link的值与SelectedCategory的值匹配,则为待创建的元素添加高亮样式
}
定义购物车实体(在文件夹 Entities 中定义):
public class Cart
{
private List<CartLine> lineCollection = new List<CartLine>(); public IEnumerable<CartLine> Lines { get { return lineCollection; } } //通过该属性对购物车的内容进行访问 //添加
public void AddItem(Product product, int quantity)
{
CartLine line = lineCollection.Where(p => p.Product.id == product.id).FirstOrDefault(); //添加之前要分购物车里是否已经有该商品
if (line == null)
{
lineCollection.Add(new CartLine { Product = product, Quantity = quantity });
}
else
{
line.Quantity += quantity;
}
} //移除
public void RemoveLine(Product product)
{
lineCollection.RemoveAll(l => l.Product.id == product.id);
} //计算总价
public decimal ComputeTotalValue()
{
return lineCollection.Sum(e => e.Product.Price * e.Quantity);
} //清空
public void Clear()
{
lineCollection.Clear();
}
} public class CartLine //表示又客户所选的一个产品和用户想要购买的数量
{
public Product Product { get; set; }
public int Quantity { get; set; }
}
产品信息列表 + “加入购物车”按钮:
@model SportsStore.Domain.Entities.Product <div class="well">
<h3>
<strong>@Model.Name</strong>
<span class="pull-right label label-primary">@Model.Price.ToString("c")</span>
</h3>
<!-- 添加“加入购物车”按钮 -->
@using (Html.BeginForm("AddToCart", "Cart"))
{
<div class="pull-right">
<!-- 给表单添加一组隐藏的子标签 -->
@Html.HiddenFor(x => x.id)
@Html.Hidden("returnUrl",Request.Url.PathAndQuery)
<!-- “加入购物车”按钮 -->
<input type="submit" class="btn-success" value="加入购物车" />
</div>
}
<span class=" lead">@Model.Description</span>
</div>
实现购物车控制器(CartController):
public class CartController : Controller
{
private IProductsRepository repository;
//带有依赖项的构造器
public CartController(IProductsRepository repo)
{
repository = repo;
} public ViewResult Index(string returnUrl)
{
return View(new CartIndexViewModel { Cart = GetCart(), ReturnUrl = returnUrl });
} #region 对于这两个方法,这里使用了与 HTML 表单中 input 元素相匹配的参数名(分部视图ProductSummary中的表单),这可以让 MVC框架将输入的表单的 POST变量自动与这些参数关联起来。(笔者不需要自己去处理)
public RedirectToRouteResult AddToCart(int id, string returnUrl)
{
Product product = repository.Products.FirstOrDefault(p => p.id == id);
if (product != null)
{
GetCart().AddItem(product, );
}
return RedirectToAction("Index", new { returnUrl });
} public RedirectToRouteResult RemoveFromCart(int id, string returnUrl)
{
Product product = repository.Products.FirstOrDefault(p => p.id == id);
if (product != null)
{
GetCart().RemoveLine(product);
}
return RedirectToAction("Index", new { returnUrl });
}
#endregion //获取购物车
private Cart GetCart()
{
Cart cart = (Cart)Session["Cart"];
if (cart == null)
{
cart = new Cart();
Session["Cart"] = cart; //使用ASP.NET的会话状态特性存储和接收Cart对象(本程序中的购物车并没有保存的数据库——持久性不够)
}
return cart;
}
}
显示购物车所需视图模型:
public class CartIndexViewModel
{
public Cart Cart { get; set; }
public string ReturnUrl { get; set; }
}
显示购物车内容的视图:
@model SportsStore.WebUI.Models.CartIndexViewModel @{
ViewBag.Title = "购物车";
} <h2>购物车</h2>
<table class="table">
<!-- 表头 -->
<thead>
<tr>
<th>商品</th>
<th>数量</th>
<th class="text-right">单价</th>
<th class="text-right">总价</th>
</tr>
</thead>
<!-- 表格内容。给这些元素的 class 属性所赋的值用于表格和元素的对齐方式 -->
<tbody>
@foreach (var line in Model.Cart.Lines)
{
<tr>
<td class="text-left">@line.Product.Name</td>
<td class="text-center">@line.Quantity</td>
<td class="text-right">@line.Product.Price.ToString("c")</td>
<td class="text-right">@((line.Quantity*line.Product.Price).ToString("c"))</td>
</tr>
}
</tbody>
<!-- 表格底部 -->
<tfoot>
<tr>
<td colspan="" class="text-right">合计:</td>
<td class="text-right">@Model.Cart.ComputeTotalValue().ToString("c")</td>
</tr>
</tfoot>
</table>
<div class="text-center">
<a class="btn btn-primary" href="@Model.ReturnUrl">继续购买</a>
</div>
该视图枚举了购物车中的各条信息,并为各条信息添加了一个表格行。
新建 ASP.NET MVC 项目快速代码的更多相关文章
- 在ASP.NET MVC项目中使用极验验证(geetest)
时间 2016-03-02 18:22:37 smallerpig 原文 http://www.smallerpig.com/979.html 主题 ASP.NET MVC geetest开发体 ...
- 1.2 认识ASP.NET MVC项目结构
1.开发环境 操作系统:xp.vista.windows 7.windows 8.windows server 2003|2008|2008R2|2012: 集成开发环境IDE: Vsiual Stu ...
- 在 ASP.NET MVC 项目中使用 WebForm、 HTML
原文地址:http://www.cnblogs.com/snowdream/archive/2009/04/17/winforms-in-mvc.html ASP.NET MVC和WebForm各有各 ...
- ASP.NET MVC项目
ASP.NET MVC项目里创建一个aspx视图 先从控制器里添加视图 视图引擎选"ASPX(C#)",使用布局或模板页不要选. 在Views\EAV目录里,生成的aspx是个单独 ...
- 习题-任务2初始ASP.NET MVC项目开发
一.选择题 1.在ASP.NET MVC项目的RouteConfig.cs文件中,( )方法注册了默认的路由配置. A.RegisterMap B.RegisterRoutes C. ...
- 2.2 利用项目模板创建ASP.NET MVC项目
1.启动VS2012,点击“文件|新建|项目”. 2.在新建项目的窗口中,选择ASP.NET MVC 4应用程序. 3.在新ASP.NET MVC 4项目窗口中的“选择模板”列表中选择“基本”模板,在 ...
- 基于BUI开发Asp.net MVC项目
因工作性质参于并开发过一些Web应用程序,前端项目框架也用了不少,比如MiniUI.ExtJS.以及定制的项目前端框架.无意中看到BUI前端框架,第一眼就被它的优雅布局所吸引.简洁的项目门户Banne ...
- ASP.NET MVC项目实现BasePage基类用作ASPX.CS网页继承
在ASP.NET MVC项目开发,还是需要创建一些Web Page来实现一些功能,如呈现报表等... 但是一旦项目的.ASPX网页太多了,其中的程序代码也会有代码冗余,出现这些情况,我们得需要对这些代 ...
- ASP.NET MVC项目中App_Code目录在程序应用
学习ASP.NET MVC,如果你是开发ASP.NET MVC项目的,也许你去为项目添加前ASP.NET项目的APP_Code目录,在这里创建与添加的Class类,也许你无法在MVC项目所引用. 那这 ...
随机推荐
- web前端----JavaScript的DOM(一)
一.什么是HTML DOM HTML Document Object Model(文档对象模型) HTML DOM 定义了访问和操作HTML文档的标准方法 HTML DOM 把 HTML 文档呈现 ...
- Python3 判断文件和文件夹是否存在、创建文件夹
Python3 判断文件和文件夹是否存在.创建文件夹 python中对文件.文件夹的操作需要涉及到os模块和shutil模块. 创建文件: 1) os.mknod(“test.txt”) 创建空文件 ...
- 06: Django Admin
目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...
- golang debug调试
1. debug by gdb: office doc download the runtime-gdb file. $ wget -q -O - https://golang.org/src/run ...
- Python3基础 help 查看内置函数说明
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- HTML语法分析
什么是HTML htyper text markup language 即超文本标记语言HTML是一个网页的主体部分,也是一个网页的基础.因为一个网页可以没有样式,可以没有交互,但是必须要有网页需要呈 ...
- SQL NULL
表 select CHARACTER_MAXIMUM_LENGTH from information_schema.columns where table_name= 'Alliance' selec ...
- JavaScript 题目
1. ],b=a; b[]=; console.log(a+b); a=[], b=a, b=[]; console.log(a+b); 2.快速排序法 var quickSort = functio ...
- Harmonic Number (调和级数+欧拉常数)题解
Harmonic Number In mathematics, the nth harmonic number is the sum of the reciprocals of the first n ...
- 【附12】grafana配置文件
一.配置文件位置 /usr/local/opt/grafana/share/grafana/default.ini /usr/local/etc/grafana/grafana.ini 二.init格 ...