Tuesday, 8 October 2013

Create OData Web Services and Use Filter Expressions

OData
(Open Data Protocol) lets you expose your resources and let the clients
directly do the queries over it. Earlier when we used to use SOAP, you expose
some methods, which performs some operations over the data returns back you the
results, and if any client needs some specific data, then we used to changes
our services by exposing down a new method which returns the needed output. But
with OData also known as Resource Oriented architecture, we can just expose the
resources or the data and let the client make the queries according to the
requirement.

Here
in this article of mine I will show you how to create a simple OData Service
and let the client make queries just like SQL queries over it to retrieve the
required data. Queries can be made by just specifying the filter expressions in
the URL only.

So to
start with I have created a WCF Service Application.

After creating we need to create a Data Service, which is
done by just the following, some simple steps: Right click on the WCF
application, and Add WCF Data Service as shown in the screenshot below.

I have highlighted in yellow, to get the service ready to be
used we need to specify the Data Source Class, this can be achieved by simply
providing Entity Framework Model for a particular database. So what this Data Source
class should support is IQueryable properties over the exposed entities. Entity
Framework model exposes all your entities as IQueryable properties. It allows directly
exposing your tables and letting the client make queries over it by using
Filter Expressions.

But for the sake of keeping it simple I am not creating
Entity Framework model and will be creating a Data context class which have
IQueryable properties.

So let’s look into how to create DataContext Class, before
that we need to create some entities (Data Service Entities) which will be
exposed as IQueryable entities via this DataContext class, here I will be
creating a single entity User:

[DataServiceKey("Id")]

[DataServiceEntity]

publicclassUser

{

publicint Id { get; set; }

publicstring Name { get; set; }

publicint Age { get; set; }

}

Attribute has been added specifying the User class as Data
Service Entity. Now we will create a context class:

publicclassSampleContext

{

#region
Static Constructor

///<summary>

/// In this static constructor i am creating some data which
will be filled into users list, the purpose of creating static constructor is
that it will be executed once

/// on the creating of very first object and fills in some
data into the users list which we can use to run through the demo.

///</summary>

static SampleContext()

{

users = newList<User>();

User user1 = newUser();

user1.Id = 1;

user1.Name = "Abhishek1";

user1.Age = 20;

User user2 = newUser();

user2.Id = 2;

user2.Name = "Abhishek2";

user2.Age = 30;

User user3 = newUser();

user3.Id = 3;

user3.Name = "Abhishek3";

user3.Age = 40;

users.Add(user1);

users.Add(user2);

users.Add(user3);

}

#endregion

#region
Private Members

staticIList<User> users;

#endregion

#region
Public Methods

publicIQueryable<User> Users

{

get

{

return users.AsQueryable();

}

}

#endregion

}

Now you can see that I have provided the Data Source for the
Data Service we created earlier to this context class:

With this we are ready to use this service:

So above you can see that the Data Service is working, and
the format in which it is displayed above is the Atom pub format. By default it
doesn’t exposes the Data Context we created and set in the Data source in the
service. For achieving so what we have to do is in the service code just
uncomment the code highlighted in yellow, what this code do is, it defines the
Entity access rule for the entities (Which all entities are needed to be
exposed) so what we doing is we are exposing the entity Users below and are
setting the Access level to Read, so we are only allowing Read operations.

publicclassSampleWCFDataService : DataService<SampleContext>

{

// This
method is called only once to initialize service-wide policies.

publicstaticvoid InitializeService(DataServiceConfiguration config)

{

// TODO:
set rules to indicate which entity sets and service operations are visible,
updatable, etc.

Now if you will access the Service again you will see
something like below:

So here we get a new collection users, which we can use in
the URL (Same as REST format) to get the users collection.

So here we are getting the Users Collection in the Atom PUB
format shown above. So what’s the use of this is we can make a request to this URL
(http://localhost/SampleWCFDataService.svc/Users)
from a Web Page or a JavaScript file (Data can be returned in JSON format) can
use the output i.e. Users list in the Web Page.

If we understand the format above we can see that it already
provides the things to determine how we can query down the Data Source or can
user filter expressions in it. Just for the sake of understanding I am
formatting the output above in XML Format.

This is how the service works and we can actually directly
consume the data into the Web Page where we need to. Now we will look into how
to use filter expression directly while accessing the Data Service and retrieve
the results. There are lot filter expressions available:

About Me

I am currently working as a Technical Lead and have 5+ Years of experience in development of Web based application in C#, Asp.Net and Sql server. My work experience also includes developing some mobile based applications.