A Partial View is just a view that is rendered inside another view. It helps to break a large view into smaller components to remove code duplication and increase reusability. By using partial views you can help your fellow developers to understand the code much faster and easily. In this tutorial I will teach how to use Partial Views in your ASP.NET MVC application, this includes their binding from the Model and Rendering inside the Parent View.
I take the example of a Student’s Record that contains his – Name, Age, Address & Marks.
First add a model and name it StudentPV.cs. Next add the below content to it.
namespace PV.Models
{
public class StudentPV
{
public string name { get; set; }
public int age { get; set; }
public AddressPV address { get; set; }
public MarksPV[] marks { get; set; }
public StudentPV(string nameVal, int ageVal, AddressPV addressVal, MarksPV[] marksArray)
{
name = nameVal;
age = ageVal;
address = addressVal;
marks = marksArray;
}
}
public class AddressPV
{
public int houseNo { get; set; }
public string street { get; set; }
public AddressPV(int houseNoVal, string streetVal)
{
houseNo = houseNoVal;
street = streetVal;
}
}
public class MarksPV
{
public string subject { get; set; }
public int marks { get; set; }
public MarksPV(string subjectVal, int marksVal)
{
subject = subjectVal;
marks = marksVal;
}
}
}
In the Student class I have 4 properties:
AddressPV class contains the house number and street of the student. Similarly the MarksPV class contains the subject and marks of the student.
In the controller I will add values to the StudentPV class. So on top of the Index Action create the object of this class and add values through its Constructor. The code is given below:
namespace PV.Controllers
{
public class PartialViewController : Controller
{
StudentPV student = new StudentPV("Ram", 20, new AddressPV(150,"Naples Street"), new MarksPV[] { new MarksPV("Maths", 90), new MarksPV("Science", 80), new MarksPV("Physics", 95) });
public ActionResult Index()
{
return View(student);
}
}
}
Note: I have added 3 subjects and their marks using the class constructor as shown above.
In the Index view I can bind the model fields and show the entire Student’s information like this:
@using PV.Models
@model PV.Models.StudentPV
<table>
<tbody>
<tr>
<td>
@Html.LabelFor(model => model.name)
</td>
<td>
@Html.DisplayFor(model => model.name)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.age)
</td>
<td>
@Html.DisplayFor(model => model.age)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.address)
</td>
<td>
<div class="address">
@Html.DisplayFor(model => model.address)
</div>
</td>
</tr>
@foreach (MarksPV mark in Model)
{
<tr>
<td class="burlywoodColor">@Html.DisplayFor(m => mark.subject)</td>
<td>@Html.DisplayFor(m => mark.marks)</td>
</tr>
}
</tbody>
</table>
Clearly, on the Index view I am looping through each object of MarksPV class to show the subject and marks of the student.
I can replace this code with a Partial View. To do this create a new View in the Index View folder and name it Marks.cshtml. Cut & Paste the foreach loop code from the Index view to Marks view.
@model PV.Models.MarksPV[]
@using PV.Models
@foreach (MarksPV mark in Model)
{
<tr>
<td class="burlywoodColor">@Html.DisplayFor(m => mark.subject)</td>
<td>@Html.DisplayFor(m => mark.marks)</td>
</tr>
}
I have to call this Partial View from the Index View which I can do from the @Html.Partial() helper method.
So the Updated Index View code becomes:
@model PV.Models.StudentPV
<table>
<tbody>
<tr>
...
</tr>
...
@Html.Partial("Marks", Model.marks)
</tbody>
</table>
Note: I have moved the @using PV.Models from this Index view to the Marks view. To call the Partial View Marks, I used the HTML.Partial() helper and passed these 2 things:
A Child Action Method is an Action that is invoked from the @Html.Action() helper. So for calling my Partial View (Marks.cshtml) I have to create a Child Action in my Controller.
Add a Child Action Method in the Controller and name it GetMarks.
public ActionResult GetMarks()
{
return PartialView("Marks", student.marks);
}
The GetMarks() child action uses PartialView() method to return the Partial View called Marks and passes student.marks property to it.
To call this Child Action in the Index View I just have to use.
@Html.Action("GetMarks")
I can filter the Marks shown by the Partial View using DropDownList. For this add the below code to the Index view:
<tr>
<td colspan="2">
<label>Loading Partial View with Child Action Method</label>
@using (Html.BeginForm())
{
@Html.DropDownListFor(m => m.marks, new List<SelectListItem> { new SelectListItem { Text = "All", Value = "All" }, new SelectListItem { Text = "Maths", Value = "Maths" }, new SelectListItem { Text = "Science", Value = "Science" }, new SelectListItem { Text = "Physics", Value = "Physics" } }) <input type="submit" value="Submit" />
}
</td>
</tr>
@if (ViewBag.Selection != null)
{
@Html.Action("GetMarks", new { subject = ViewBag.Selection })
}
Here I added a form which contains a DropDownList (DDL) and a button. The DDL contains the student’s marks, and on clicking the button only the marks of the selected subject is shown.
You can also see that I used a ViewBag variable for not calling the child action in case of a null value. This makes the binding to only take place when the button is clicked.
Also note that I am now passing the subject as the second parameter of the @Html.Action() helper.
Now change the code of the GetMarks() child action in the controller with this new one:
public ActionResult GetMarks(string subject)
{
if (subject != "All")
{
student.marks = student.marks.Where(x => x.subject == subject).ToArray();
return PartialView("Marks", student.marks);
}
}
Also add Index Post Action method to the controller that will be called on the button click, and will pass the filtered Model based on DDL selection.
[HttpPost]
[ActionName("Index")]
public ActionResult Index_Post(string marks)
{
if (marks != "All")
student.marks = student.marks.Where(x => x.subject == marks).ToArray();
ViewBag.Selection = marks;
return View(student);
}
When using the jQuery AJAX method there is no page PostBack as the Child Action Method is called asynchronously.
I will also provide filtering feature with jQuery AJAX. So add the below code to the Index View:
<tr>
<td colspan="2">
<label class="displayBlock">Loading Partial View with jQuery AJAX</label>
<select id="subjectSelect" name="marks">
<option value="All">All</option>
<option value="Maths">Maths</option>
<option value="Science">Science</option>
<option value="Physics">Physics</option>
</select> <button id="bindButton">Submit</button>
</td>
</tr>
<tr>
<td colspan="2">
<table id="partial"></table>
</td>
</tr>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
$(document).ready(function () {
$("#bindButton").click(function (e) {
$.ajax({
type: "POST",
url: "/PartialView/GetMarks",
contentType: "application/json; charset=utf-8",
data: '{"subject":"' + $("#subjectSelect").val() + '"}',
dataType: "html",
success: function (result, status, xhr) {
$("#partial").html(result)
},
error: function (xhr, status, error) {
alert("Result: " + status + " " + error + " " + xhr.status + " " + xhr.statusText)
}
});
});
});
</script>
Download the codes:
I hope you learned how necessary and powerful a Partial View can be. Use it whenever you want to make your code cleaner and understandable to other coders. Please share this article using the social media buttons given below.