Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Rendering a Partial View and JSON Data Using AJAX in ASP.NET MVC

0.00/5 (No votes)
18 Sep 2014 1  
This article explains how to render a partial view and JSON data using AJAX.

Introduction

This article explains how to render a partial view and JSON data using AJAX. I have divided this article into three sections to understand both concepts, the first section describes the basic code and structure that is common in both concepts, the second section describes how to render a partial view using AJAX and the last section describes how to render JSON data on a web using AJAX.

I will explain these concepts with a simple example. The example is that books are showing on the web depending on publisher. I choose a publisher from a dropdown list then the books information is shown in the web page depending on publisher. So let’s see this example in detail.

Getting Started

I add the ADO.NET Entity Model to the application to do the database operations mapped from the “Development” database. The ADO.NET Entity Model is an Object Relational Mapping (ORM) that creates a higher abstract object model over ADO.NET components. This ADO.NET Entity Model is mapped the with “Development” database so context class is “DevelopmentEntities” that inherits the DbContext class.

This “Development” database has two tables, one is the Publisher table and the other is the BOOK table. Both tables have 1-to-many relationships, in other words one publisher can publish multiple books but each book is associated with one publisher. If you want to learn more about this application database design, then please check my previous article An MVC Application with LINQ to SQL.

The ADO.NET Entity Model is mapped to both tables. The connection string for this has the same name as the context class name and this connection string is created in the web.config file. You can change the name of the connection string. The context class name and connection string name is just a convention, not a configuration, so you can change it with a meaningful name. The following Figure 1.1 shows the ADO.NET Entity Model mapping with both tables.

The ADO.NET Entity Model mapping with Publisher and Book tables.

Figure 1.1 The ADO.NET Entity Model mapping with Publisher and Book tables.

Now the ADO.NET Entity Model is ready for the application and it's time to move on the next step of the application that is the model design so let’s see the application’s model.

Model Design

As you already know, the purpose of the application is to create two entities (Publisher and BOOK) that I have already created as the same therefore I need to create two models, one for the publisher and the other for the books.

I create a publisher model (Publisher.cs) under the Model folder that has a publisher id and publisher list as in the following code snippet.

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
 
namespace JsonRenderingMvcApplication.Models
{
    public class PublisherModel
    {
        public PublisherModel()
        {
            PublisherList = new List<SelectListItem>();
        }
 
        [Display(Name="Publisher")]
        public int Id { get; set; }
        public IEnumerable<SelectListItem> PublisherList { get; set; }
    }
}

After the publisher model, I create a book model (Book.cs) in the same folder. That has basic properties related to a book. The following is a code snippet for the book model.

namespace JsonRenderingMvcApplication.Models
{
    public class BookModel
    {
        public string Title { get; set; }
        public string Author { get; set; }
        public string Year { get; set; }
        public decimal Price { get; set; }
    }
}

Now the models are ready for use so now to move on to the controller.

Controller Design

I create two controllers, one for publisher that shows a publisher’s list in a dropdown list and another is a book controller that shows book details depending on publisher. The publisher controller defines a single action method that is the same in both concepts; rendering a partial view and JSON data while the book controller defines two action methods, one for partial view rendering and another for JSON data rendering so you will look at it later in this article.

Now create a publisher controller (PublisherController.cs) under the Controllers folder as per the MVC convention. This control has a single action method to show the publisher list on the view. The following is a code snippet for the publisher controller.

using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using JsonRenderingMvcApplication.Models;
 
namespace JsonRenderingMvcApplication.Controllers
{
    public class PublisherController : Controller
    {
        public ActionResult Index()
        {
            PublisherModel model = new PublisherModel();
            using (DAL.DevelopmentEntities context = new DAL.DevelopmentEntities())
            {
                List<DAL.Publisher> PublisherList = context.Publishers.ToList();
                model.PublisherList = PublisherList.Select(x =>
                                        new SelectListItem()
                                        {
                                            Text = x.Name,
                                            Value = x.Id.ToString()
                                        });
                                 }
            return View(model);
        }
    }
}

Now create book a controller (BookController.cs) under the Controllers folder of the application and leave it empty without any action method, you will define two action methods in this controller, one for partial view rendering and another for JSON data rendering. Now the article’s first section is completed as defined in the introduction and now to move both approaches one by one.

Rendering a Partial View

When making AJAX requests, it is very simple to return HTML content as the result. Simply return an ActionResult using the PartialView method that will return rendered HTML to the calling JavaScript.

Now define an action method in the book controller that returns an ActionResult using the PartialView. This action method retrieves a list of books depending on publisher id that passes as a parameter in this action method. The following is a code snippet for this action method.

public ActionResult BookByPublisher(int id)
{
    IEnumerable<BookModel> modelList = new List<BookModel>();
    using (DAL.DevelopmentEntities context = new DAL.DevelopmentEntities())
    {
        var books = context.BOOKs.Where(x => x.PublisherId == id).ToList();
        modelList = books.Select(x =>
                   new BookModel()
                    {
                             Title = x.Title,
                             Author = x.Auther,
                             Year = x.Year,
                             Price = x.Price
                   });
    }
    return PartialView(modelList);  
 }

I define a route for this action in the RegisterRoute() method under the RouteConfig class (App_Start/RouteConfig.cs).

routes.MapRoute("BookByPublisher",
       "book/bookbypublisher/",
        new { controller = "Book", action = "BookByPublisher" },
        new[] { "JsonRenderingMvcApplication.Controllers" });

Now create a view for the publisher that has a dropdown list for the publisher and shows the book details depending on the value selected in the publisher dropdown list using AJAX. This view is an index (Views/Publisher/Index.cshtml). The following is a code snippet for the Index view.

@model JsonRenderingMvcApplication.Models.PublisherModel
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript"> 
   
    $(document).ready(function ()
    {
        $("#Id").change(function ()
        {
             var id = $("#Id").val();
             var booksDiv = $("#booksDiv");
             $.ajax({
                 cache: false,
                 type: "GET",
                 url: "@(Url.RouteUrl("BookByPublisher"))",
                data: { "id": id },
                success: function (data)
                {
                    booksDiv.html('');
                    booksDiv.html(data);
                },
                error: function (xhr, ajaxOptions, thrownError)
                {
                    alert('Failed to retrieve books.');                    
                }
            });
        });
    });      
</script>
<div>
    @Html.LabelFor(model=>model.Id)
    @Html.DropDownListFor(model => model.Id, Model.PublisherList)
</div>
<div id="booksDiv">
</div>

Run the application and choose an item from the publisher dropdown list. You will then get the result as in Figure 1.2.

 output result using HTML rendering

Figure 1.2 output result using HTML rendering

Rendering JSON Data

In the previous section, you have learned that you can render an HTML on AJAX request but in this section you will learn about rendering only serialized data, not entire HTML. ASP.NET MVC offers native JSON support in the form of the JsonResult action result, which accepts a model object that it serialized into the JSON format. In order to add AJAX support to your controller actions via JSON, simply use the Controller.Json() method to create a new JsonResult containing the object to be serialized.

Now, create an action method BooksByPublisherId() in the book controller that returns JsonResult. This action method retrieves a list of books depending on publisher id that passes as a parameter in this action method. The following is a code snippet for this action method.

public JsonResult BooksByPublisherId(int id)
{
      IEnumerable<BookModel> modelList = new List<BookModel>();
      using (DAL.DevelopmentEntities context = new DAL.DevelopmentEntities())
      {
            var books = context.BOOKs.Where(x => x.PublisherId == id).ToList();
            modelList = books.Select(x =>
                        new BookModel()
                        {
                                   Title = x.Title,
                                   Author = x.Auther,
                                   Year = x.Year,
                                    Price = x.Price
                           });
            }
            return Json(modelList,JsonRequestBehavior.AllowGet);
        }

The action method was created to return book details. Here the Controller.Json() method has two parameters, the first one is for the data source that will be serialized and the second parameter is JsonRequestBehavior.AllowGet, which explicitly informs the ASP.NET MVC Framework that it’s acceptable to return JSON data in a response to an HTTP GET request.

The JsonRequestBehavior.AllowGet parameter is necessary in this case because, by default, ASP.NET MVC disallows returning JSON in response to an HTTP GET request in order to avoid potentially dangerous security vulnerability known as JSON hijacking.

This action method returns JSON data as shown in Figure 1.3.

 JSON Data from action method

Figure 1.3 JSON Data from action method

I define a route for this action in the RegisterRoute() method under the RouteConfig class (App_Start/RouteConfig.cs).

routes.MapRoute("BooksByPublisherId",
      "book/booksbypublisherid/",
       new { controller = "Book", action = "BooksByPublisherId" },
       new[] { "JsonRenderingMvcApplication.Controllers" });

Now, modify the previously created Index view for the publisher that has a dropdown list for the publisher and that shows the book details depending on selecting a value in the publisher dropdown list using AJAX. The following is a code snippet for the Index view:

@model JsonRenderingMvcApplication.Models.PublisherModel
 
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
    $(document).ready(function () {
        $("#Id").change(function () {
            var id = $("#Id").val();
            var booksDiv = $("#booksDiv");
            $.ajax({
                cache: false,
                type: "GET",
                url: "@(Url.RouteUrl("BooksByPublisherId"))",
                data: { "id": id },
                success: function (data) {
                    var result = "";
                    booksDiv.html('');
                    $.each(data, function (id, book) {
                        result += '<b>Title : </b>' + book.Title + '<br/>' +
                                    '<b> Author :</b>' + book.Author + '<br/>' +
                                     '<b> Year :</b>' + book.Year + '<br/>' +
                                      '<b> Price :</b>' + book.Price + '<hr/>';
                    });
                    booksDiv.html(result);
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert('Failed to retrieve books.');
                }
            });
        });
    });
</script>
<div>
    @Html.LabelFor(model=>model.Id)
    @Html.DropDownListFor(model => model.Id, Model.PublisherList)
</div>
<div id="Div1">
</div>

Run the application and choose an item from the publisher dropdown list; you will then get the result as in Figure 1.4.

output result using JSON data rendering

Figure 1.4: Output result using JSON data rendering

Conclusion

Which one is fast? You can say that JSON data rendering is faster compared to partial view rendering. I make the same request using both approaches and get response data in bytes as shown in the following table.

Content Type Header Body Total (Byte)
text/html 434 375 809
application/ json 398 197 595
Table 1.1: Summary of response bytes

It is a big difference when working with a small amount of server data. When I represent these statistics using a circle graph, then these look like:

circle graph

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here