When to use Html.RenderPartial and Html.RenderAction in ASP.NET MVC Razor Views
TweetIn this blog post I want to show examples when to use Html.RenderPartial and Html.RenderAction when creating web sites in ASP.NET MVC using the Razor view engine.
Some background information on Html.RenderAction and Html.RenderPartial
Html.RenderAction is a somewhat contentious feature because it invokes a controller action.
This means each time it’s called a new request (which has to go through the ASP.NET MVC pipeline) is made.
As shown below ASP.NET MVC requests are routed to a controller. It’s the controller that decides what view to call and what data (model) to pass to it.
A view has one responsibility and that’s to render HTML. It’s supposed to be simple, it doesn’t know (or care) where the data in the model comes from.
The thing MVC traditionalists frown upon is the fact that Html.RenderAction can execute child actions in ASP.NET MVC views.
However given that Html.RenderAction just like an AJAX request is a form of sub request, the case against seems somewhat outdated and doesn’t take into the account using Html.RenderAction will allow you to separate concerns of models and controllers as we will see later in this post.
For Html.RenderPartial the content of the partial view is added to content of the host view, either directly to the response output (or by using a StringWriter if you use or Html.Partial).
Examples of when to use Html.RenderPartial and Html.RenderAction
The mockup below shows a blog post with comments and a list of categories in a side bar.
When to use Html.RenderPartial (or Html.Partial)
For the page we’re designing I would create a view to show the blog post and call Html.RenderPartial to output the comments
@model WhenToUseRenderActionAndRenderPartial.Models.ShowPostViewModel
@{
ViewBag.Title = Model.Post.Title;
}
<section>
<article>
<header>
<h1>@Model.Post.Title</h1>
Posted on | <time datetime="@Model.Post.DatePublished.ToString("s")">
@Model.Post.DatePublished.ToLongDateString()
</time> | @Model.Comments.Count() Comments
</header>
@Html.Raw(Model.Post.Content)
</article>
</section>
@{Html.RenderPartial("_Comments", Model.Comments);}
The partial view for comments would look like this
@model IEnumerable<WhenToUseRenderActionAndRenderPartial.Models.Comment>
<section>
<header>
<h3>
Comments</h3>
</header>
@foreach (var comment in Model)
{
<article>
<header>
@comment.Author on
<time datetime="@comment.DateCreated.ToString("s") ">
@comment.DateCreated.ToLongDateString()
</time>
</header>
<img alt="@comment.Author" src=@comment.ImageUrl />
<p>
@comment.Content
</p>
</article>
}
</section>
This means the ShowPost action in the Blog controller
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using WhenToUseRenderActionAndRenderPartial.Models;
namespace WhenToUseRenderActionAndRenderPartial.Controllers
{
public class BlogController : Controller
{
public ActionResult ShowPost()
{
ShowPostViewModel viewModel = new ShowPostViewModel();
viewModel.Post = new Post
{
Title = "Blog Title",
Content = "<p>Lorem ipsum dolor sit amet</p>",
DatePublished = new DateTime(2010, 10, 5)
};
viewModel.Comments = new List<Comment>()
{
new Comment()
{
Author = "Andrew",
Content = "I think",
DateCreated = new DateTime(2010, 10, 5)
},
new Comment()
{
Author = "Bill",
Content = "I reckon",
DateCreated = new DateTime(2010, 10, 5)
},
new Comment()
{
Author = "Chris",
Content = "My opinion",
DateCreated = new DateTime(2010, 10, 6)
}
};
return View(viewModel);
}
}
}
needs to pass a model with properties for the blog post and its comments to the view.
public class Post
{
public string Title { get; set; }
public string Content { get; set; }
public DateTime DatePublished { get; set; }
}
public class Comment
{
public string Content { get; set; }
public string Author { get; set; }
public string ImageUrl { get; set; }
public DateTime DateCreated { get; set; }
}
public class ShowPostViewModel
{
public Post Post { get; set; }
public IEnumerable<Comment> Comments { get; set; }
}
When to use Html.RenderAction (or Html.Action)
So while we could add a property for categories to the ShowPostViewModel used for the ShowPost page and use Html.RenderPartial to display them, we have to add a category property to every model in our solution where categories are shown.
public class ShowPostViewModel
{
public Post Post { get; set; }
public IEnumerable<Comment> Comments { get; set; }
public IEnumerable<Category> Categories { get; set; }
}
public class AnotherViewModel
{
public string StringToOutput { get; set; }
public IEnumerable<Category> Categories { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
}
And using a base class with a categories property and have ViewModel classes inherit from it would just be bloating models with unrelated data and concerns.
public class ViewModelBase
{
public IEnumerable<Category> Categories { get; set; }
}
public class ShowPostViewModel : ViewModelBase
{
public Post Post { get; set; }
public IEnumerable<Comment> Comments { get; set; }
}
So if you want to display the same information on multiple pages and the data doesn’t necessarily depend on or isn’t related to the rest of the page, something like a widget to display categories then I would use Html.RenderAction.
As shown in the markup below Html.RenderAction is called from the layout page for the blog post.
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
</head>
<body>
@RenderBody()
@{Html.RenderAction("Show", "Category");}
</body>
</html>
Jag Reehal’s Final Thought on ‘When to use Html.RenderPartial and Html.RenderAction in ASP.NET MVC Razor Views’
In cases where a model for the page is already populated with all the information required I would use Html.RenderPartial.
If the same information is shown on multiple pages it’s likely that the data needs to be in its own model so I would use Html.RenderAction. As shown in this post I would say layout pages are going to the most common place Html.RenderAction will be used.
-
nick4eva
-
Cesar
-
http://www.lessonist.com niaher
-
Joseph
-
nenadg
-
Jet
-
Forest
-
Kevin Grieger
-
tan
-
Alextito52
-
Fraas
-
Dan
-
http://www.facebook.com/people/Jon-Swoveland/773837989 Jon Swoveland
-
Leon
-
Anonymous
-
Wiebe Tijsma
-
Dipanki99
-
Andre
-
http://www.facebook.com/storefront.doors Storefront Doors
-
Naresh Kumar
