Using ASP.NET MVC Partial Views for Dynamic JavaScript Rendering

Published on Author nickriggs6 Comments

Using partial views in ASP.NET MVC is a simple strategy to have a single code base for rendering both the initial display of the model and dynamic additions to the model. The advantage of this method is having a single .NET class (the partial view) for rendering data. The disadvantage is the client side code needs to make a post to the server for each modification to the model.

For example, we have a very simple model consisting of a Customers table:

simplecustomermodel

Our controller’s Index() action send a model consisting of an array of all the customers to the view:

public ActionResult Index()
{
    //create and return the intial model
    using (var data = new DataContext())
        return View(data.Customers.ToArray());
}

The Index view renders the model, notice that the individual customers are passed to a partial view:

<table id="CustomerList">
    <thead>
        <tr>
            <td>
                Cutomer Id
            </td>
            <td>
                First Name
            </td>
            <td>
                Last Name
            </td>
        </tr>
    </thead>
    <tbody>
        <% foreach (var customer in Model)
           {
               Html.RenderPartial("CustomerListItem", customer);
           } %>
    </tbody>
    <tfoot>
        <tr>
            <td>
                <input type="button" id="AddButton" value="Add"></input>
            </td>
            <td>
                <input type="text" id="FirstNameInput" maxlength="32" />
            </td>
            <td>
                <input type="text" id="LastNameInput" maxlength="32" />
            </td>
        </tr>
    </tfoot>
</table>

The CustomerListItem partial view simply renders a single row of the table:

<tr>
    <td><%= Model.CustomerId %></td>
    <td><%= Model.FirstName %></td>
    <td><%= Model.LastName %></td>
</tr>

Now we have a page that displays all the customers in our model. We also have some controls at the bottom of the table to add a new customer. Before we can make those controls work, we need to add an action to our controller for creating a new customer:

public ActionResult CreateCustomer(Customer customer)
{
    //add the new customer to the databvase
    using (var data = new DataContext())
    {
        data.Customers.InsertOnSubmit(customer);
        data.SubmitChanges();
    }

    //render the new customer's listitem and return the result
    return PartialView("CustomerListItem", customer);
}

Notice that this action is passing the new customer directly to the CustomerListItem partial view and returns the result, which will be the rendered Html. Now that we have our action, let’s add some jQuery on the client to post the new customer’s FirstName and LastName. Once the post has been processed and returns with the new customer’s rendered View, we will need to append the Html to the existing table:

$(document).ready(function() {

    $("#AddButton").click(function() {

        var firstName = $("#FirstNameInput").val();
        var lastName = $("#LastNameInput").val();

        $.post("/Home/CreateCustomer", { "firstName": firstName, "lastName": lastName }, function(result) {

            $("#CustomerList tbody").append($(result));

        });
    });
});

The result is page that displays our model, plus allows us to add new customers to the model. The best thing about this approach is that the rendering code is in one place, the partial view.

The downside of this approach is that adding a new customer and retrieving the new rendered Html requires a round-trip to the server. This approach also requires you to modify the model (database) on each edit to keep the state in sync. In a future post, I’ll discuss that allows for one code base for rendering, without the mentioned short comings. UPDATE: Here is that very post.

Source Code: partialviewsfordynamicrendering.zip

6 Responses to Using ASP.NET MVC Partial Views for Dynamic JavaScript Rendering

Leave a Reply

Your email address will not be published. Required fields are marked *