XYZCONSULTING

3/17/2010

OData = Hotness

Microsoft has officially announced OData.  If you are not aware of what this is, then in a sentence: OData is a queryable REST based interface that exposes your data via AtomPub.

 

To publish a feed, you have to use .Net.  However, they have provided client sdk’s for a variety of languages to allow for simple querying of the exposed services and they are working on several more.

 

I strongly encourage you to check it out.

 

Partly to give an idea of what is possible, and partly for my own reference, I am going to repost a “cheat sheet” that I found online at Meta-Me

 

 

The Service:

It all starts with a Data Service hosted somewhere:

http://server/service.svc

 

Basic queries:

You access the Data Service entities through resource sets, like this:

http://server/service.svc/People

You request a specific entity using its key like this:

http://server/service.svc/People(16)

Or by using a reference relationship to something else you know:

http://server/service.svc/People(16)/Mother

This asks for person 16’s mother.

Once you have identified an entity you can refer to it’s properties directly:

http://server/service.svc/People(16)/Mother/Firstname

 

$value:

But the last query wraps the property value in XML, if you want just the raw property value you append $value to the url like this:

http://server/service.svc/People(16)/Mother/Firstname/$value

 

$filter:

You can filter resource sets using $filter:

http://server/service.svc/People?$filter=Firstname  eq ‘Fred’

Notice that strings in the filter are single quoted.

Numbers need no quotes though:

http://server/service.svc/Posts?$filter=AuthorId eq 1

To filter by date you have identity the date in the filter, like this:

http://server/service.svc/Posts?$filter=CreatedDate eq DateTime'2009-10-31'

You can filter via reference relationships:

http://server/service.svc/People?$filter=Mother/Firstname eq 'Wendy'

The basic operators you can use in a filter are:

Operator

Description

C# equivalent

eq

equals

==

ne

not equal

!=

gt

greater than

>

ge

greater than or equal

>=

lt

less than

<

le

less than or equal

<=

and

and

&&

or

or

||

()

grouping

()

There are also a series of functions that you can use in your filters if needed.

 

$expand:

If you want to include related items in the results you use $expand like this:

http://server/service.svc/Blogs?$expand=Posts

This returns the matching Blogs and each Blog’s posts.

 

$select:

Some Data Services allow you to limit the results to just the properties you require – aka projection – for example if you just want the Id and Title of matching Posts you would need something like this:

http://server/service.svc/Posts?$select=Id,Title

You can even project properties of related objects too, like this:

http://server/service.svc/Posts?$expand=Blog&$select=Id,Title,Blog/Name

This projects just the Id, Title and the Name of the Blog for each Post.

 

$count:

If you just want to know how many records would be returned, without retrieving them you need $count:

http://server/service.svc/Blogs/$count

Notice that $count becomes one of the segments of the URL – it is not part of the query string – so if you want to combine it with another operation like $filter you have to specify $count first, like this:

http://server/service.svc/Posts/$count?$filter=AuthorId eq 6

This query returns the number of posts authored by person 6.

 

$orderby:

If you need your results ordered you can use $orderby:

http://server/service.svc/Blogs?$orderby=Name

Which returns the results in ascending order, to do descending order you need:

http://server/service.svc/Blogs?$orderby=Name%20desc

To filter by first by one property and then by another you need:

http://server/service.svc/People?$orderby=Surname,Firstname

Which you can combine with desc if necessary.

 

$top:

If you want just the first 10 items you use $top like this:

http://server/service.svc/People?$top=10

 

$skip:

If you are only interested in certain page of date, you need $top and $skip together:

http://server/service.svc/People?$top=10&$skip=20

This tells the Data Service to skip the first 20 matches and return the next 10. Useful if you need to display the 3rd page of results when there are 10 items per page.

Note: It is often a good idea to combine $top & $skip with $orderby too, to guarantee the order results are retrieved from the underlying data source is consistent.

 

$inlinecount & $skiptoken:

Using $top and $skip allows the client to control paging.

But the server also needs a way to control paging – to minimize workload need to service both naive and malicious clients – the OData protocol supports this via Server Driven Paging.

With Server Driven Paging turned on the client might ask for every record, but they will only be given one page of results.

This as you can imagine can make life a little tricky for client application developers.

If the client needs to know how many results there really are, they can append the $inlinecount option to the query, like this:

http://server/service.svc/People?$inlinecount=allpages

The results will include a total count ‘inline’, and a url generated by the server to get the next page of results.

This generated url includes a $skiptoken, that is the equivalent of a cursor or bookmark, that instructs the server where to resume:

http://server/service.svc/People?$skiptoken=4

 

$links

Sometime you just need to get the urls for entities related to a particular entity, which is where $links comes in:

http://server/service.svc/Blogs(1)/$links/Posts

This tells the Data Service to return links – aka urls – for all the Posts related to Blog 1.

 

$metadata

If you need to know what model an OData compliant Data Service exposes, you can do this by going to the root of the service and appending $metadata like this:

http://server/service.svc/$metadata

This should return an EDMX file containing the conceptual model (aka EDM) exposed by the Data Service.

4/4/2008

Exploring WCF

I have been learning Windows Communication Foundation (WCF) recently.  While there are a LOT of frustrations involved with it, it is leaps and bounds better than what was previously available in the .Net world.

One thing I have discovered about WCF though is that there is precious little information about it available (in comparison to other .Net related topics) .  With that in mind, I thought I would start sharing some of the things that I am learning.

First of all WCF does its work through contracts.  The two main types of contracts that we'll focus on here are Service Contracts, Operation Contracts, and Data Contracts.  A Service Contract describes which operations the client can perform on the service. Operation Contracts expose a method as a operation to perform as part of the service. Data Contracts define which data types are passed to and from the service.

The contracts are applied to your classes, methods, variables as attributes.
For instance:

[ServiceContract]
interface ISample
{
//Will be included in the  service
[OperationContract]
string  SayHelloSample(string name);

//Not included as part of  the service
string SayGoodbyeSample(string  name);
}

In the above example, we are defining an interface for a service and exposing SayHelloSample as a operation for that service.  Only classes/interfaces with the ServiceContract attribute and methods with OperationContract will be recognized by WCF.

So, now that we've covered some of the basics, let's jump into a project...

Using Visual Studio Click on File > New Project
Choose your favorite language and the Select Web in the tree and select WCF Service Application
Visual Studio will stub out a service for you automatically. 

You will have 3 files for each service you create.

  • An Interface for the service - ISample.cs
    It is generally considered best practice (and in fact WCF was designed with this in mind) to define your contracts in a separate interface that you then use to implement your service in a separate class.
  • The Service file itself - Sample.svc
    The "visible" file people will connect to when calling your service
  • The Code-Behind for the Service - Sample.svc.cs
    This is where you will code the behavior for the operations defined in the contract interface.

Visual Studio implements the infamous "Hello World" to lay out a simple service for you to start from.

Let's start by examining the interface.  The first thing to notice will be the namespaces that are imported to support WCF ( System.Runtime.Serialization and System.ServiceModel).  If you are going to add contracts to any existing classes or objects you may have, then you will need to make sure these two namespaces are included in your using/imports.

The interface defined here will have two methods: GetData and GetDataUsingDataContract.  Given the similarity to the previous interface sample I have already shown, I won't write out the code here, but notice that the Service and Operation contract attributes are on the interface and methods.

Under the interface you should see a class defined called CompositeType.  Here is an example of a Data Contract. 

[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get {  return stringValue; }
set { stringValue = value; }
}
}

You will notice the DataContract attribute applied to the class.  This is telling WCF that we want this class/struct to be part of our service contract and to serialize it for incoming/outgoing messages. Inside the class/struct itself, for each property / variable that we would like WCF to take not of and serialize, we decorate it with the DataMember attribute.  Much like with the OperationContracts, anything that does NOT have the DataMember attribute will be ignored by WCF.

Looking at the code behind that was generated for our service, we will see that it is inheriting from the contract interface.  Notice here that because the contracts were already specified in the interface, we do not specify them here on the class itself.

public class Sample : ISample
{
public string GetData(int value)
{
return string.Format("You  entered: {0}", value);
}
public  CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite.BoolValue)
{
composite.StringValue +=  "Suffix";
}
return composite;
}
}

When GetDataUsingDataContract is called, WCF will take care of serializing the CompositeType class to the appropriate format depending on what kind of service you are developing.  In this case, XML. Also, be sure to open the web.config and look at the new system.ServiceModel section at the bottom.  This is where the service gets exposed/defined and will be where you will configure the security and accessibility of your service.  I will be writing more on this in the future.

As you can imagine, if you have existing code already written with custom objects / methods, by simply adding the appropriate attributes, it becomes very simple to expose them via WCF.

I highly encourage everyone to dig into WCF and poke around.  It is an incredibly robust and powerful framework and is a definite step forward for .Net based services.