在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
在上一篇文章中,我创建了一个Blog项目,今天我打算继续折腾一下这个项目。
主要讲一下自己对ASP.NET MVC3中的局部视图以及缓存的认识,不多说先上几幅图吧。 第一幅图是博客首页分页栏的截图,第二幅图就是博客的Sidebar了。我分别用 ASP.NET MVC3 提供的两种局部视图实现。 有人可能会问,为什么要用两种不同的方法,你这不是装13吗? 。。。。我想我只能“呵呵”以对了,使用什么方法当然是根据需求而选的。 第三幅图是完成后的页面结构 先说分页栏吧要做成上面的导航栏,我们需要哪些数据呢? 1. 当前页码 2. 每页显示多少文章 3. 数据库里有多少文章 OK,既然只要需要这些,那我们就在HomeController的IndexAction里通过ViewBag提供给他吧。 public class HomeController : Controller { BlogDB db = new BlogDB(); // GET: /Home/page/5 public ActionResult Index(int page = 1) { int countPerPage=10; var posts = db.Posts.Include("Category") .Include("Tags").Include("Comments") .OrderByDescending(p=>p.CreateTime) .Skip((page - 1) * countPerPage) .Take(10); ViewBag.CurrentPage = page; ViewBag.CountPerPage = countPerPage; ViewBag.PostsCount = posts.Count(); return View(posts); } } 数据有了,就让我们开始创建局部视图吧。 打开右击View文件夹中的Share文件夹,选择添加视图。我这里将他命名为_Pagination,注意
打开刚刚创建好的视图,添加如下代码 @{ int pageCount = ViewBag.PostsCount / ViewBag.CountPerPage + 1; int currentPage = ViewBag.CurrentPage; } <div class="pagination"> <span class="first_page"><a href="/">First</a></span> @for (var i = 1; i <= pageCount; i++) { if (i == currentPage) { <span class="page_num current_page"> <a href="/page/@i">@i</a> </span> } else { <span class="page_num "> <a href="/page/@i">@i</a> </span> } } @if (currentPage == pageCount) { <span class="next_page"><a href="/page/@pageCount">Next</a></span> } else { <span class="next_page"><a href="/page/@(currentPage+1)">Next</a></span> } </div> 我们在Home Index View中调用这个局部视图 @model IEnumerable<Blog.Models.Post> @{ ViewBag.Title = "NinoFocus | Notepad"; } <div > @Html.Partial("_PostList", Model) <!-- 看这里,看这里,我们通过下面的语句调用他 --> @Html.Partial("_Pagination") </div> <!--#END main--> 恩,好了,分页栏就算完成了。 接下来SidebarSidebar 和 分页栏 不同,因为分页栏只在首页显示,所有首页可以提供数据给他。而Sidebar确实无论哪个页面都要显示的,所以他必须要自己给自己提供数据。 好,看到这里可能有人会想,那还不和上面的一样吗?我在页面上写一些服务器端的代码,提供数据会死啊? 就像这样 <li> <h4 class="h4"> <span>一些酷酷的 <strong>网站</strong></span></h4> <ul> @foreach (var link in new Blog.Models.BlogDB().FriendLinks) { <li> <a href="@link.URL" title="@link.Name"> <strong>@link.Name</strong> </a> - @link.Description </li> } </ul> </li> 会死吗?当然不会啦,这也是一种解决方法啊(虽然我不推荐在)。但是,我想想又觉得不妥啊,Sidebar的数据更新频率很低的啊,这样每次刷新页面或者浏览其他页面都要重新请求数据库,这是不是不妥啊? 为了让他变得妥妥的,同时也充分的压榨一下ASP.NET MVC的特性。我还是决定使用ChildAction了。 添加一个ChildActionController,主要负责一些局部视图的工作(其实就是提供数据用的)。下面我以Sidebar中的友情链接为例,说一下Action的代码。 [ChildActionOnly] [OutputCache(Duration = 3600)] public PartialViewResult SidebarFriendLinks() { var links = db.FriendLinks; return PartialView(links); } [ChildActionOnly] 属性说明这个Action只能内部调用,不能被外部单独访问。 [OutputCache] 启用缓存,Duration字段是缓存时间,以秒为单位,这里我设为1小时。 为了您的健康Action的返回值类型还是用 PartialViewResult 不要用平时常用的 ActionResult ,不然会死很多脑细胞的,我昨晚就被这个搞死。 ASP.NET MVC 遵循DRY(Don't repeat yourself)原则,如果你没有为ActionResult的View指定模板页的话,他会自动的给你加上默认的模板页。默认的模板页可以在_ViewStart.cshtml文件中指出 @{ Layout = "~/Views/Shared/_Layout.cshtml"; }
让我们模拟一下页面的调用,我们在使用了模板页的页面中调用SidebarFriendlinks,然后SidebarFriendLinks有调用了模板,然后模板页调用了SidebarFriendLinks,然后。。。。然后你就悲剧了啊。 如果您一定要使用ActionResult作为返回值的话,那就给局部页面加上下面的语句吧 @{ Layout = null; } 所以为了健康,还是使用PartialViewResult吧。 恩,就此打住,让我们继续吧。右击SidebarFriendLinks选择添加视图。 让我们打开SidebarFriendLinks.cshtml文件,修改一下@model 后的语句,然后添加页面代码 @model IEnumerable<Blog.Models.FriendLink> <li> <h4 class="h4"> <span>一些酷酷的 <strong>网站</strong></span></h4> <ul> @foreach (var link in Model) { <li> <a href="@link.URL" title="@link.Name"> <strong>@link.Name</strong> </a> - @link.Description </li> } </ul> </li> 然后在_Sidebar.cshtml中调用他 <div class="sidebar"> <ul> @Html.Action("SidebarTags","ChildAction") @Html.Action("SidebarArchive","ChildAction") @Html.Action("SidebarFriendLinks","ChildAction") </ul> </div> <div class="clear"> </div> <!-- END sidebar --> 这样写的 sidebar 以后我是不是就可以通过配置文件来控制里面的内容了呢,嘎嘎噶!!! 最后奉上_Layout.cshtml的代码,只求大家对这个博客的页面结构有个更加清晰的了解 <!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> <link href="Content/Site.css" rel="stylesheet" type="text/css" /> </head> <body class="homepage"> <div > @Html.Partial("_Header") @Html.Partial("_Navigation") <div > <div > @RenderBody() </div> @Html.Partial("_Sidebar") </div> </div> @Html.Partial("_Footer") <!-- Script --> @RenderSection("footerScript",false) <!-- End Script--> </body> </html> @RenderBody() 就是其他页面填充内容的地方。 @RenderSection("footerScript",false) 预留的空间,第一个参数表示名称,第二个参数如果是false的话,表示不是每个页面都必须往里面添加内容;如果是true的话,就表示使用了这个模板的页面都必须往里面填写内容。 在页面上,可以这样调用 @section footerScript{ ...javascript here } 看看缓存是否有效打开SQL Server Profiler来监视一下数据库请求。 1. 未开启缓存时在没有开启缓存的情况下,我每次刷新博客首页,会有5条(我sidebar里放了3个局部页面)数据库请求 为什么使用EF时同样的SQL语句会被请求两次?求解!!! 我这里暂且算他一次先。 2. 开启缓存时现在我启用sidebar的缓存,来看看刷新页面的数据库请求次数 请求次数从5次,变成2次了。说明缓存成功开启了。呵呵,有点爽爽的。 于是贪得无厌的我又把首页也加了缓存 // // GET: /Home/page/5 [OutputCache(Duration=60*5)] public ActionResult Index(int page = 1) 现在刷新页面看看 没有数据库连接请求了,啦啦啦啦。 貌似博客园的首页也加了缓存吧,好像一两分钟的样子。 ASP.NET MVC
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论