Inserting with OData

My boss asked me to add the ability to insert new jobs using the jobs oData service I wrote about a few posts ago.

First, add the ability to write data:

public static void InitializeService(DataServiceConfiguration config)
{
    config.SetEntitySetPageSize("*", 50); // limit to 50 rows
    config.SetEntitySetAccessRule("Jobs", EntitySetRights.AllRead | EntitySetRights.WriteAppend | EntitySetRights.ReadSingle); 
    ...

Again, the only problem with this is that anyone on the internet can access this and write data.
So we need to add a ChangeInterceptor to make sure the user is authenticated:

[ChangeInterceptor("Jobs")]
public void OnChangeEntries(Job job, UpdateOperations operations)
{
    if (!HttpContext.Current.Request.IsAuthenticated)
    {
        throw new DataServiceException("You must be authenticated to create a new Job.");
    }
}

And that’s it, all done.

Advertisement

Playing with OData

OData is the bomb.

I just spent a few days creating a quick ASP.NET MVC3 website for a client. Nothing fancy, and thanks to MVC’s scaffolding the job was done quickly enough. Then the client asked me to create a web service so that another one of their systems could access it in the future.

Hi Matt,
Need you to write a simple API that allows us to query the job bag DB with an Job Number and return back the Client Ref (if available). Ideally – if you can extend out the API to return all data for a record we can use this for other things in the future also.

Come talk if you need more than this back of fag packet spec :)

Well, with 6 lines of code it was done. Right-click Web project, Add New Item, WCF Data Service.

public class JobService : DataService<JobSystemEntities>
{
    // This method is called only once to initialize service-wide policies.
    public static void InitializeService(DataServiceConfiguration config)
    {
        config.SetEntitySetPageSize("*", 50); // limit to 50 rows

        config.SetEntitySetAccessRule("Jobs", EntitySetRights.AllRead); // allow querying of all jobs e.g. http://localhost:34031/JobService.svc/Jobs            
        // config.SetEntitySetAccessRule("Jobs", EntitySetRights.ReadSingle); // need to specify a job e.g. http://localhost:34031/JobService.svc/Jobs(1001)

        config.SetEntitySetAccessRule("Clients", EntitySetRights.AllRead);
        config.SetEntitySetAccessRule("Departments", EntitySetRights.AllRead);
        config.SetEntitySetAccessRule("JobTypes", EntitySetRights.AllRead);

        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    }

I used Jeff and Tim’s PDC10 screencast (which I linked to a few posts ago) as a reference on how to do this. (They add the OData service 45 mins in).

Too easy. Using that we can do all sorts of awesome queries, like: