2LeggedSpider

Serializing a PartialView as JSON in ASP.NET MVC

Posted in ASP.NET by Sumit Thomas on November 5, 2009

[tweetmeme style=”compact”]In certain situations you might want to make an AJAX request to load a Partial View (UserControl) and display in a web page. It was quite easy to accomplish that using AJAX.NET Update Panels. Though jQuery doesn’t have any Update Panels of its own, it is quite easy to accomplish the same. In this post, I will try to make an AJAX request to fetch a UserControl as JSON and display it on the screen. Alright, so follow me…

1) Create a Partial View name PostList as follows…

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Post>>" %>
<table border="0" width="100%">
    <thead>
        <tr>
            <th>
                Post ID
            </th>
            <th>
                Title
            </th>
            <th>
                Description
            </th>
            <th>
                Created On
            </th>
        </tr>
    </thead>
    <tbody>
        <%foreach (MyMVCTrials.Models.Post p in Model)
          { %>
        <tr>
            <td>
                <%=p.PostID.ToString() %>
            </td>
            <td>
                <%=p.Title %>
            </td>
            <td>
                <%=p.Description %>
            </td>
            <td>
                <%=p.CreatedOn %>
            </td>
        </tr>
        <%} %>
    </tbody>
</table>

2) Create a Entity class named Post as follows…

    public class Post
    {
        public int PostID { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public string CreatedOn { get; set; }
    }

3) Create a private method in the Controller class, say PostController, to prepare a List of Posts and return it.

        private IList<Post> GetPosts()
        {
            IList<Post> posts = new List<Post>();

            for (int i = 1; i <= 10; i++)
            {
                Post post = new Post();
                post.PostID = i;
                post.Title = String.Format("My Post Title #{0}", i.ToString());
                post.Description = String.Format("My Description {0}", i.ToString());
                post.CreatedOn = DateTime.Now.ToLongDateString();
                posts.Add(post);
            }
            return posts;
        }

4) Create a private method in your Controller which will execute the PartialView and return a JSON string of the view.

        private JsonResult SerializeControl(string controlPath, object model)
        {
            ViewPage page = new ViewPage();
            ViewUserControl ctl = (ViewUserControl)page.LoadControl(controlPath);
            page.Controls.Add(ctl);
            page.ViewData.Model = model;
            page.ViewContext = new ViewContext();
            System.IO.StringWriter writer = new System.IO.StringWriter();
            System.Web.HttpContext.Current.Server.Execute(page, writer, false);
            string outputToReturn = writer.ToString();
            writer.Close();
            return this.Json(outputToReturn.Trim());
        }

5) Create the following Action Methods in your Controller

        //Returns the View that will display the List of Posts based on an AJAX call.
        public ActionResult Index()
        {
            return View();
        }

        //Returns the serialized JSON string of the partial view, PostList
        public JsonResult PostList()
        {
            System.Threading.Thread.Sleep(3000);
            return SerializeControl("~/Views/Shared/PostList.ascx", GetPosts());
        }

6) And finally, in our Index View Page, add the following…

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript">
    $(document).ready(function() {
        $("#loadPosts").click(function() {
            $("#postList").html("Loading Posts....");
            $.getJSON("/Home/PostList", function(data) {
                if (data) {
                    $("#postList").html(data);
                }
            });

        });
    });
</script>

<input type="button" id="loadPosts" value="Load Posts!" />
<div id="postList" />
</asp:Content>

When you run the application, here is how it will look like…

On clicking the button
Loading Posts

Final result!
Posts Loaded

6 Responses

Subscribe to comments with RSS.

  1. links for 2009-12-21 « 2LeggedSpider said, on December 21, 2009 at 12:33 pm

    […] Serializing a PartialView as JSON in ASP.NET MVC (tags: aspnetmvc, asp.net mvc, jquery) […]

  2. gokulnath said, on January 1, 2010 at 10:18 pm

    only after setting JsonRequestBehavior, it worked!!

    return Json(data, JsonRequestBehavior.AllowGet)

    anyway thanks for your code!

  3. Brian said, on February 26, 2010 at 4:21 am

    Just for fun, take the post title and try to turn it into a link via Html.ActionLink. Throws NotImplemetedException. Oddly, Html.Encode works. Bears investigation.

  4. Himani said, on September 2, 2011 at 4:11 pm

    How to do it for Razor engine

  5. julian shaw said, on January 9, 2012 at 5:22 am

    Excellent! Thanks a lot, your post really helped.

    • Simon said, on March 20, 2014 at 10:50 pm

      Why Mine stops at Loading Posts…. I made sure I have loaded jquery and jquery-unobtrusive-ajax.cs The following are the code. Please help.

      PostController.cs:
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Web;
      using System.Web.Mvc;

      namespace TestPartialView.Controllers
      {
      public class PostController : Controller
      {
      //
      // GET: /Post/

      public ActionResult Index()
      {
      return View();
      }

      //Returns the serialized JSON string of the partial view, PostList
      public JsonResult PostList()
      {
      System.Threading.Thread.Sleep(3000);
      return SerializeControl(“~/Views/Shared/PostList.cshtml”, GetPosts());
      }

      private JsonResult SerializeControl(string controlPath, object model)
      {
      ViewPage page = new ViewPage();
      ViewUserControl ctl = (ViewUserControl)page.LoadControl(controlPath);
      page.Controls.Add(ctl);
      page.ViewData.Model = model;
      page.ViewContext = new ViewContext();
      System.IO.StringWriter writer = new System.IO.StringWriter();
      System.Web.HttpContext.Current.Server.Execute(page, writer, false);
      string outputToReturn = writer.ToString();
      writer.Close();
      return this.Json(outputToReturn.Trim(),JsonRequestBehavior.AllowGet);
      }

      private IList GetPosts()
      {
      IList posts = new List();

      for (int i = 1; i <= 10; i++)
      {
      Post post = new Post();
      post.PostID = i;
      post.Title = String.Format("My Post Title #{0}", i.ToString());
      post.Description = String.Format("My Description {0}", i.ToString());
      post.CreatedOn = DateTime.Now.ToLongDateString();
      posts.Add(post);
      }
      return posts;
      }

      }

      public class Post
      {
      public int PostID { get; set; }
      public string Title { get; set; }
      public string Description { get; set; }
      public string CreatedOn { get; set; }
      }

      }

      /Post/Index.cshtml:
      @model IEnumerable
      @{
      ViewBag.Title = “Index”;
      Layout = “~/Views/Shared/_Layout.cshtml”;
      }

      Index

      $(document).ready(function() {
      $(“#loadPosts”).click(function() {
      $(“#postList”).html(“Loading Posts….”);
      $.getJSON(“/Home/PostList”, function(data) {
      if (data) {
      $(“#postList”).html(data);
      }
      });

      });
      });

      Post.cs: in Models:
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Web;

      namespace TestPartialView.Models
      {

      public class Post
      {
      public int PostID { get; set; }
      public string Title { get; set; }
      public string Description { get; set; }
      public string CreatedOn { get; set; }
      }

      }
      and finally in all the directory of /Post /Home /Shared, I have PostList.cshtml:
      @model IEnumerable

      Post ID

      Title

      Description

      Created On


Leave a comment