Partial Views
When the same piece of HTML appears on several pages — a product card, a cart summary, a menu — write it once as a partial view and reuse it everywhere.
On this page · 6 min · Intermediate
On this page
- Learning objectives
- Explanation
- Syntax
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 6 min
- Difficulty
- Intermediate
- Updated
- Oct 29, 2026
Related tutorials
Learning objectives#
- Create and render partial views
- Pass a model to a partial
- Choose between Html.Partial and Html.RenderPartial
- Use child actions for partials that need their own data
Explanation#
A partial view is a .cshtml file without a layout, usually named with a leading underscore (_ProductCard.cshtml) and stored in the controller’s folder or Views/Shared.
@Html.Partial("_ProductCard", product) renders it and returns the HTML as a string. @{ Html.RenderPartial("_ProductCard", product); } writes directly to the response — slightly faster, same result.
A partial receives the model you pass. If you pass none, it gets the parent view’s model, which can cause “The model item passed into the dictionary is of type…” errors.
A child action renders a partial with its own data: @Html.Action("CartSummary", "Cart") runs a full action (with its own model loading) and inserts its output. Mark it [ChildActionOnly] so it cannot be requested by URL.
Controllers can also return PartialView("_Rows", items) — perfect for AJAX requests that refresh part of a page.
Syntax#
@Html.Partial("_ProductCard", product)
@{ Html.RenderPartial("_ProductCard", product); }
@Html.Action("CartSummary", "Cart") @* child action *@
Code example: A product card partial and a cart-summary child action#
// Models/Product.cs
namespace ShopSite.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
}
// Controllers/ShopController.cs
using System.Collections.Generic;
using System.Web.Mvc;
using ShopSite.Models;
namespace ShopSite.Controllers
{
public class ShopController : Controller
{
public ActionResult Index()
{
var products = new List<Product>
{
new Product { Id = 1, Name = "Gel Pen", Price = 20m },
new Product { Id = 2, Name = "Notebook", Price = 60m },
};
return View(products);
}
// Only callable from a view with Html.Action
[ChildActionOnly]
public ActionResult CartSummary()
{
ViewBag.Count = 3; // in a real app: read from the session or database
return PartialView("_CartSummary");
}
}
}
@* Views/Shop/Index.cshtml *@
@model List<Product>
@Html.Action("CartSummary")
<h1>Products</h1>
@foreach (var p in Model)
{
@Html.Partial("_ProductCard", p)
}
@* Views/Shared/_ProductCard.cshtml *@
@model Product
<div class="card">
<h2>@Model.Name</h2>
<p>@Model.Price.ToString("0.00") rupees</p>
</div>
@* Views/Shop/_CartSummary.cshtml *@
<p class="cart">Cart: @ViewBag.Count items</p>
GET /Shop
200 OK
<p class="cart">Cart: 3 items</p>
<h1>Products</h1>
<div class="card">
<h2>Gel Pen</h2>
<p>20.00 rupees</p>
</div>
<div class="card">
<h2>Notebook</h2>
<p>60.00 rupees</p>
</div>
GET /Shop/CartSummary
500 Internal Server ErrorThis example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.
Step-by-step explanation#
- Index passes a list of products to its view.
- Html.Action("CartSummary") runs the child action, which sets its own data and returns the _CartSummary partial.
- For each product, Html.Partial renders _ProductCard from Views/Shared with that product as its model.
- Partials have no layout, so only their markup is inserted.
- Requesting /Shop/CartSummary directly fails because of [ChildActionOnly] — the error page shows instead of the partial.
Real-world use case#
A bookshop shows the same book card on the home page, search results, category pages and the wishlist. One _BookCard partial means a design change (adding a “Bestseller” badge) is made once.
Common mistakes#
Calling @Html.Partial("_ProductCard") without a model passes the parent’s List<Product>, and the partial that expects Product throws a model type error.
A partial that loads its own data from a static helper is hard to test. Use a child action or load the data in the parent action.
Without it, /Shop/CartSummary is a public URL returning a bare HTML fragment.
Best practices#
- Prefix partial names with an underscore
- Always pass the model explicitly
- Use child actions for widgets that need their own data
- Return PartialView from actions used by AJAX
Remember this#
Partial = reusable piece, no layout.
Html.Partial(name, model) — pass the model.
Needs its own data? Html.Action + [ChildActionOnly].
Practice exercise#
Your task: Create a _Price partial that takes a decimal and shows it with two decimals and a “Sale!” label when it is under 50. Use it twice in a view.
Need a hint?
Show solution
// Controllers/SaleController.cs
using System.Web.Mvc;
namespace ShopSite.Controllers
{
public class SaleController : Controller
{
public ActionResult Index() => View();
}
}
@* Views/Sale/Index.cshtml *@
@Html.Partial("_Price", 30m)
@Html.Partial("_Price", 120m)
@* Views/Shared/_Price.cshtml *@
@model decimal
<p>@Model.ToString("0.00")@if (Model < 50) {<strong> Sale!</strong>}</p>
GET /Sale 200 OK <p>30.00<strong> Sale!</strong></p> <p>120.00</p>
Mini quiz#
What is the difference between Html.Partial and Html.RenderPartial?
Want more? Practise all ASP.NET MVC MCQs · ASP.NET MVC interview questions
My notes#
Saved in this browser.