Trang chủ » ASP.NET » Understanding Partial Views in ASP.NET MVC Application

Understanding Partial Views in ASP.NET MVC Application


Abstract:
In ASP.NET WebForms, UserControls were used to break the application into smaller pieces. Each piece represented an important part of the application. In ASP.NET MVC application you can achieve the same effect using RenderPartial and RenderAction methods. In this article we are going to demonstrate how to use RenderPartial to construct and use partial views.
Understanding RenderPartial:
RenderPartial serves the purpose of rendering a UserControl in an ASP.NET MVC application. The views rendered are called PartialViews. In order to use a partial view in your application add a MVC UserControl to your application. The screenshot below shows which project template to select when adding a user control to your MVC application.

You can add the MVC View UserControl in your current view folder or in the shared folder. First the view folder will be searched for the specified user control followed by the shared folder.
We have added a simple "Categories.ascx" to our views folder. Now, let’s see how we can load the partial views on the page. Inside the view page you can load the partial view using RenderPartial HTML helper method.

Code Snippet
  1. <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"><h2>List</h2>
  2. <% Html.RenderPartial("Categories"); %> </asp:Content>

 

Now, if you run the page you will see that the partial view is loaded inside the view page as shown in the screenshot below:

Passing Data to Partial View:
In the previous example our partial view was independent which means it was not dependent on any data populated by the view page. In real world applications this might not be the case. We may need to pass additional data to our partial view. The good news is that the partial view has access to the same ViewData dictionary which is used by the view page.
Consider a situation in which we need to pass a list of categories to the partial view. The view page List.aspx has the controller CategoryController. The controller List action is responsible for populating the categories in the ViewData as shown below:

 

Code Snippet
  1. public ActionResult List()
  2. {
  3. var categories = new List<Category>(){new Category() {Name = "Beverages"},new Category() {Name = "Condiments"},new Category() {Name = "Meat"}};ViewData["Categories"] = categories;return View();
  4. }

 

Now, the Categories.ascx partial view can easily access the ViewData["Categories"] as shown below:


 

Code Snippet
  1. <h2>Categories</h2><% foreach (var category in ((IEnumerable<Category>)ViewData["Categories"])){ %><li><%= category.Name %></li><% } %>

This shows that the ViewData dictionary is shared between the view page and the view user control (partial view). We can even make it better by strong typing the partial view and sending the model as a second parameter to the RenderPartial method. The code below shows how to make the ViewUserControl as a strongly typed view which can handle IEnumerable<Category> collection.

Code Snippet
  1. <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Category>>" %><%@ Import Namespace="MyMVCApplication.Models"%><%@ Import Namespace="Microsoft.Web.Mvc"%><h2>Categories</h2><% foreach (var category in Model){ %><li> <%= category.Name %> </li>
  2. <% } %>

 

And here is the RenderPartial method passing the Model as the second parameter.


 

Code Snippet
  1. <% Html.RenderPartial("Categories",ViewData["Categories"]); %>

Or even better you can assign the ViewData.Model and use that to pass the Model to the RenderPartial method.

Code Snippet
  1. <% Html.RenderPartial("Categories",Model); %>

The result is shown below:

Since, the ViewData dictionary is shared between the ViewUserControl and the ViewPage you can easily make changes to the object in the ViewUserControl and it will be reflected in the ViewPage using the controller.
Caching Partial Views:
In WebForms you could easily cache the contents of the UserControl. Let’s check out how we can cache partial views in an ASP.NET MVC application.
Using OutputCache Directive:
The most direct way of caching the partial views is by using the OutputCache directive. Let’s add the directive on the ViewUserControl and see the result.


 

Code– Sokhanh03 Blog
  1. <%@ OutputCache Duration="60" VaryByParam="None" %><h2>Categories</h2>Categories.ascx: <%= DateTime.Now.ToLongTimeString() %>

We are caching the ViewUserControl to "60" seconds which means it is cached to 1 minute. The DateTime is displayed on the view to indicate the request time. The DateTime value will indicate if the partial view is cached or not.  
The view page List.aspx is also adjusted. It now includes an ActionLink which will call the "List" action. It also consists of a DateTime indicator just like ViewUserControl.

Code Snippet
  1. List.aspx: <%= DateTime.Now.ToLongTimeString() %><% Html.RenderPartial("Categories",Model); %><%= Html.ActionLink<CategoryController>( x=> x.List(),"Show List") %>

When you run the page and click the "Show List" button you will find out that the view user control "Categories" is never cached. Both the view page and the view user control will show the same time. There is a problem inHtml.RenderPartial which prevents it from caching the user control. Html.RenderPartial method completely ignores the OutputCache directive in the user control. 
Using OutputCache Action Filters:
Our next technique is to use the OutputCache action filters to cache the contents of the action. This means that we need to return the user control from the controller action. This is performed by using RenderAction HTML helper method. The render action method will invoke the action on the controller and inject the returned HTML to the calling page.

Code Snippet
  1. List.aspx: <%= DateTime.Now.ToLongTimeString() %><% Html.RenderAction("PartialList"); %><%= Html.ActionLink<CategoryController>( x=> x.List(),"Show List") %>

The RenderAction in the above code will invoke the "PartialList" action which is defined below:


 

Code Snippet
  1. [OutputCache(Duration = 60, VaryByParam = "None")]public ActionResult PartialList(){var categories = new List<Category>(){new Category() {Name = "Beverages"},new Category() {Name = "Condiments"},new Category() {Name = "Meat"}};ViewData.Model = categories;return View("Categories");}

The result is shown in the screenshot below:

The screenshot above shows that the complete view page along with the partial view is cached. Once, again we have failed to cached the component. Let’s see our last approach.
WebForms Engine to the Rescue:
Phil Haack blogged about this method a while ago. He leveraged the power of the WebForms engine to cache the partial view. You can read his post here.
The idea is simple! We are going to use our view user control as a ASP.NET WebForms user control using arunat="server" tag. First, we need to register our user control in the directive which is accomplished using the following code:


 

Code Snippet
  1. <%@ Register Src ="~/Views/Category/Categories.ascx" TagName="Partial" TagPrefix="mvc" %>

Now, we can use the UserControl in our page using the code below:

 

Code Snippet
  1. <mvc:Partial runat="server" />

Now, if you run the application and click the "Show List" button you will notice that the user control is cached at a differen t time than the page.

Hopefully, in the future release of MVC the defect in RenderPartial wil be fixed!  
Conclusion:
In this article we learned about Partial Views. We also learned how to perform caching using partial views. In the next article we are going to take a look at the RenderAction HTML helper method and how it can be used in an ASP.NET MVC application.
[Download Sample]

Advertisements

Bình luận

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s