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