ASP.NET MVC3 小技巧:局部視圖和緩衝

來源:互聯網
上載者:User
文章目錄
  • 先說分頁欄吧
  • 接下來Sidebar
  • 看看緩衝是否有效

在上一篇文章中,我建立了一個Blog項目,今天我打算繼續折騰一下這個項目。

如果你還不瞭解ASP.NET MVC3的布局,你可以先看看這篇文章,應該會對你有所協助的。

主要講一下自己對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,注意

小技巧 : 在 ASP.NET MVC3 中,如果一個視圖以"_"開頭命名的話,外部是不能單獨訪問他的,他只能作為局部視圖嵌套在其他視圖中。

開啟剛剛建立好的視圖,添加如下代碼

@{    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 id="main">@Html.Partial("_PostList", Model)<!-- 看這裡,看這裡,我們通過下面的語句調用他 -->@Html.Partial("_Pagination")</div><!--#END main-->

恩,好了,分頁欄就算完成了。

接下來Sidebar

Sidebar 和 分頁欄 不同,因為分頁欄只在首頁顯示,所有首頁可以提供資料給他。而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";}

如果你看了我上面推薦的關於ASP.NET MVC3布局的文章,你會知道這是好東西的。

讓我們類比一下頁面的調用,我們在使用了模板頁的頁面中調用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 id="container">      @Html.Partial("_Header")        @Html.Partial("_Navigation")        <div id="body">            <div id="content">                @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
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.