World’s simplest OData service

Published on March 26, 2010

I get frustrated sometime trying to play around with new Microsoft technologies.  The process usually involves;  install this CTP, apply this hotfix, create a project using this template, and this item using another template.  By then end I may have something working but I don’t know what magic happened behind the scenes.

Here is a bare bones implementation of an OData service, no magic allowed (Ok, without actually going to the command line compiler). 

What you will need for this experiment is:

1) .Net Framework 3.5 sp1

2) A new Visual Studio 2008 console application

3) These references

    • System
    • System.Core
    • System.ServiceModel          <—This brings in the WCF stack
    • System.ServiceModel.Web <—This brings in the Web friendly WCF service host
    • System.Data.Services         <—This brings in the OData service host

 

4) and this code

using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Linq;

namespace ODataConsoleService { class Program { static void Main(string[] args) {

        <span class="kwrd">string</span> serviceAddress = <span class="str">&quot;http://localhost:998&quot;</span>;
        Uri[] uriArray = { <span class="kwrd">new</span> Uri(serviceAddress) };
        Type serviceType = <span class="kwrd">typeof</span>(CustomerDataService);

        <span class="kwrd">using</span> (var host = <span class="kwrd">new</span> DataServiceHost(serviceType, uriArray)) {
            host.Open(); 
            Console.WriteLine(<span class="str">&quot;Press any key to stop service&quot;</span>);
            Console.ReadKey();
        }

    }

}

<span class="rem">// Expose IQueryable properties as read-only Atom collections</span>
<span class="kwrd">public</span> <span class="kwrd">class</span> CustomerDataService : DataService&lt;CustomerService&gt; {
    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> InitializeService(IDataServiceConfiguration config) {
        config.SetEntitySetAccessRule(<span class="str">&quot;*&quot;</span>, EntitySetRights.AllRead);
    }
}


<span class="rem">// Expose list of customers Customer as IQueryable</span>
<span class="kwrd">public</span> <span class="kwrd">class</span> CustomerService {
    <span class="kwrd">private</span> List&lt;Customer&gt; _List = <span class="kwrd">new</span> List&lt;Customer&gt;();

    <span class="kwrd">public</span> CustomerService() {

        _List.Add(<span class="kwrd">new</span> Customer() { ID = 1, Code = <span class="str">&quot;BLAH&quot;</span>, Name = <span class="str">&quot;Blah&quot;</span> });
        _List.Add(<span class="kwrd">new</span> Customer() { ID = 2, Code = <span class="str">&quot;Bob&quot;</span>, Name = <span class="str">&quot;Bob's Hardware&quot;</span> });
        _List.Add(<span class="kwrd">new</span> Customer() { ID = 3, Code = <span class="str">&quot;Bill&quot;</span>, Name = <span class="str">&quot;Bills Fishmongers&quot;</span> });
    }

    <span class="kwrd">public</span> IQueryable&lt;Customer&gt; Customers {
        get {
            <span class="kwrd">return</span> _List.AsQueryable&lt;Customer&gt;();
        }
    }

}

<span class="rem">// Entity to expose in atom:Entry</span>
<span class="kwrd">public</span> <span class="kwrd">class</span> Customer {
    <span class="kwrd">public</span> <span class="kwrd">int</span> ID { get; set; }  <span class="rem">// ID is required to be a viable OData entity</span>
    <span class="kwrd">public</span> <span class="kwrd">string</span> Code { get; set; }
    <span class="kwrd">public</span> <span class="kwrd">string</span> Name { get; set; }
}

}

 

That’s it.  That’s all you need to expose a complete Atom Pub compliant service exposing your objects.

Once you have that, you can Run the program and use a web browser to browse to http://localhost:998 to see the collections.   Don’t forget to look in the magic url http://localhost:998/$metadata  Sorry, some magic I am still trying to figure out how to remove!

Credit goes to Alex James and Phani for getting me most of the way there.