Using jQuery and OData to Insert a Database Record

In my previous blog entry, I explored two ways of inserting a database record using jQuery. We added a new Movie to the Movie database table by using a generic handler and by using a WCF service. In this blog entry, I want to take a brief look at how you can insert a database record using OData.

Introduction to OData

The Open Data Protocol (OData) was developed by Microsoft to be an open standard for communicating data across the Internet. Because the protocol is compatible with standards such as REST and JSON, the protocol is particularly well suited for Ajax.

OData has undergone several name changes. It was previously referred to as Astoria and ADO.NET Data Services.

OData is used by Sharepoint Server 2010, Azure Storage Services, Excel 2010, SQL Server 2008, and project code name “Dallas.” Because OData is being adopted as the public interface of so many important Microsoft technologies, it is a good protocol to learn.

You can learn more about OData by visiting the following websites:

http://www.odata.org

http://msdn.microsoft.com/en-us/data/bb931106.aspx

When using the .NET framework, you can easily expose database data through the OData protocol by creating a WCF Data Service. In this blog entry, I will create a WCF Data Service that exposes the Movie database table.

Create the Database and Data Model

The MoviesDB database is a simple database that contains the following Movies table:

clip_image001

You need to create a data model to represent the MoviesDB database. In this blog entry, I use the ADO.NET Entity Framework to create my data model. However, WCF Data Services and OData are not tied to any particular OR/M framework such as the ADO.NET Entity Framework.

For details on creating the Entity Framework data model for the MoviesDB database, see the previous blog entry.

Create a WCF Data Service

You create a new WCF Service by selecting the menu option Project, Add New Item and selecting the WCF Data Service item template (see Figure 1). Name the new WCF Data Service MovieService.svc.

clip_image003

Figure 1 – Adding a WCF Data Service

Listing 1 contains the default code that you get when you create a new WCF Data Service. There are two things that you need to modify.

Listing 1 – New WCF Data Service File

using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;

namespace WebApplication1
{
    public class MovieService : DataService< /* TODO: put your data source class name here */ >
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
            // Examples:
            // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }
}

First, you need to replace the comment /* TODO: put your data source class name here */ with a class that represents the data that you want to expose from the service. In our case, we need to replace the comment with a reference to the MoviesDBEntities class generated by the Entity Framework.

Next, you need to configure the security for the WCF Data Service. By default, you cannot query or modify the movie data. We need to update the Entity Set Access Rule to enable us to insert a new database record.

The updated MovieService.svc is contained in Listing 2:

Listing 2 – MovieService.svc

using System.Data.Services;
using System.Data.Services.Common;

namespace WebApplication1
{
    public class MovieService : DataService<MoviesDBEntities>
    {
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("Movies", EntitySetRights.AllWrite);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }
}

That’s all we have to do. We can now insert a new Movie into the Movies database table by posting a new Movie to the following URL:

/MovieService.svc/Movies

The request must be a POST request. The Movie must be represented as JSON.

Using jQuery with OData

The HTML page in Listing 3 illustrates how you can use jQuery to insert a new Movie into the Movies database table using the OData protocol.

Listing 3 – Default.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>jQuery OData Insert</title>

    <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.js" type="text/javascript"></script>
    <script src="Scripts/json2.js" type="text/javascript"></script>

</head>
<body>

<form>
    <label>Title:</label>
    <input id="title" />

    <br />

    <label>Director:</label>
    <input id="director" />
</form>

<button id="btnAdd">Add Movie</button>


<script type="text/javascript">

    $("#btnAdd").click(function () {
        // Convert the form into an object
        var data = { Title: $("#title").val(), Director: $("#director").val() };

        // JSONify the data
        var data = JSON.stringify(data);

        // Post it
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: "MovieService.svc/Movies",
            data: data,
            dataType: "json",
            success: insertCallback
        });
    });

    function insertCallback(result) {
        // unwrap result
        var newMovie = result["d"];

        // Show primary key
        alert("Movie added with primary key " + newMovie.Id);
    }

</script>

</body>
</html>

jQuery does not include a JSON serializer. Therefore, we need to include the JSON2 library to serialize the new Movie that we wish to create. The Movie is serialized by calling the JSON.stringify() method:

var data = JSON.stringify(data);

You can download the JSON2 library from the following website:

http://www.json.org/js.html

The jQuery ajax() method is called to insert the new Movie. Notice that both the contentType and dataType are set to use JSON.

The jQuery ajax() method is used to perform a POST operation against the URL MovieService.svc/Movies. Because the POST payload contains a JSON representation of a new Movie, a new Movie is added to the database table of Movies.

When the POST completes successfully, the insertCallback() method is called. The new Movie is passed to this method. The method simply displays the primary key of the new Movie:

clip_image005

Summary

The OData protocol (and its enabling technology named WCF Data Services) works very nicely with Ajax. By creating a WCF Data Service, you can quickly expose your database data to an Ajax application by taking advantage of open standards such as REST, JSON, and OData.

In the next blog entry, I want to take a closer look at how the OData protocol supports different methods of querying data.

Discussion

  1. Roland says:

    Very good post Stephen.
    Regards,

    R.

  2. Greg Gorman says:

    I must be missing something. Why go directly to a service? Kinda defeats the point of MVC as the service is your model or the data layer for your model.

    Why not post to a public method on the controller?

  3. Ted K says:

    Thanks. Can you show CRUD samples and/or validation?