Expose Odata Endpoint in Web API 2

In today's IT industry Odata is one of the common buzzwords. People are talking about Odata and Odata services. What can Odata do? And in which scenario? We will discuss them a little and then we will see how to expose the Odata endpoints in our Web API application.

So, let's discuss what Odata is. Odata stands for Open Data protocol that was introduced by Microsoft in an open release context then it was widely adapted by the industry. It provides an idea of uniform data access.

We know that today's IT world is on top of data, data may come from various sources and multiple ways and data will be valuable only if we can categorize it easily. Hence the idea of a uniform data access mechanism was created. The industry thought that data might come from multiple locations and multiple protocols but it would be great if we can access data uniformly from all platforms.

For example, an analyst wanted to get data from a Windows data marketplace and SQL Azure using the same mechanism, hence the concept of Odata was created.

Another example of an Odata endpoint is something like that. Let's think of an e-commerce organization sharing their data with a vendor and one vendor wants to get a report based on region by providing a region code where another wants to get a sales report by country by providing a country key. But surprisingly all the data is stored in a single place or in technical terms, in a single table.

The problem is that if tomorrow another vendor demands another type of report by supplying another key then it needs to add another function to serve the needs. This is the exact situation where Odata can rescue us.

Ok, so we have learned the fundamental idea behind Odata, now we will implement an Odata endpoint in our Web API application. In this example we have used Web API 2.0 to implement an Odata service, so please ensure that you have installed the Odata package in your application before executing this code. To install Odata please go to the NuGet Package Manager and install the following package.

Once the package is installed, we can expose an Odata endpoint in the application. In this example we are using Entity Framework and here is the table structure.

Add one .edmx file to the application and generate an entity from the table. Here I have generated the following entity from the table.

Fine, we will now write one simple controller and will expose data as an Odata endpoint and the data will come from the table (that we saw above) using the Entity Framework.

So, let's create the following controller class in the Controller folder of the application.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Data;  
  4. using System.Data.Entity;  
  5. using System.Data.Entity.Infrastructure;  
  6. using System.Linq;  
  7. using System.Net;  
  8. using System.Net.Http;  
  9. using System.Web.Http;  
  10. using System.Web.Http.ModelBinding;  
  11. using System.Web.Http.OData;  
  12. using System.Web.Http.OData.Routing;  
  13. using OdataAPI;  
  14. using OdataAPI.Models;  
  16. namespace OdataAPI.Controllers  
  17. {  
  18.     public class personController : ODataController  
  19.     {  
  20.         private ApiSecurityEntities db = new ApiSecurityEntities();  
  21.         [Queryable]  
  22.         public IQueryable<UserMaser> Getperson()  
  23.         {  
  24.             return db.UserMaser;  
  25.         }  
  26.     }  
  27. }  
Please note that the controller class is derived from the Odata controller class, not the WebApiController class and we are returning IQuerable<T> data from the Getperson() action.

This is the key point of an Odata service, rather than returning an object value or HTTP Response message we are returning IQuerable, then the client can query data from this Getperson() endpoint and finally we have decorated the action by a Querable attribute.

Fine, we have done all the setup in the controller section. Now, it's time to register an Odata endpoint in the route. Open the WebApiConfig.cs file of the application and modify it accordingly.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web.Http;  
  5. using System.Web.Http.OData.Builder;  
  6. using Microsoft.Data.Edm;  
  8. namespace OdataAPI  
  9. {  
  10.     public static class WebApiConfig  
  11.     {  
  12.         private static IEdmModel GenerateEdmModel()  
  13.         {  
  14.             var builder = new ODataConventionModelBuilder();  
  15.             builder.EntitySet<UserMaser>("person");  
  16.             return builder.GetEdmModel();  
  17.         }  
  18.         public static void Register(HttpConfiguration config)  
  19.         {  
  20.             // Web API routes  
  21.             config.MapHttpAttributeRoutes();  
  23.             config.EnableQuerySupport();  
  24.      // Map for Odata  
  25.             config.Routes.MapODataRoute("odata""odata", GenerateEdmModel());  
  27.             config.Routes.MapHttpRoute(  
  28.                 name: "DefaultApi",  
  29.                 routeTemplate: "api/{controller}/{id}",  
  30.                 defaults: new { id = RouteParameter.Optional }  
  31.             );  
  32.         }  
  33.     }  
  34. }  
Here I have created the GetEdmModel() function where I defined the Entity Class, yes UserMaster is entity name. The Map Odata route takes three arguments, the first one is the friendly name of routing, it could be anything meaningful. The second argument is the root prefix and the third argument is all the Edm Models that we want to expose as an Odata endpoint.

Fine, everything is cool and fine, now let's run the application and try to consume the Odata service from a client. In this example we will use Fiddler as our client.

If we hit http://localhost:10020/odata/person this URL then we will find the following output.

If we want to get only the first record then we can do a query like this.


And we will get the first record as output as in the following:

Ok, so we are getting a result from Fiddler. Now what if we need to access this Odata endpoint from a different application? Yes we can access the endpoint from a different application. Let's try to consume the endpoint from a console application. Add a service reference of the Odata endpoint, in my case the URL is:


And let's provide a reference of the URL in the console application.

Then consume the OData endpoint as in the following.
  1. static void Main(string[] args)  
  2. {  
  3.     Uri uri = new Uri("http://localhost:10020/odata/");  
  4.     var container = new OdataPerson.Container(uri);  
  6.     var data = container.person.Where(fn => fn.id == 1).FirstOrDefault();  
  7.     Console.WriteLine(data.name);  
  8.     Console.ReadLine();  
  9. }  

In this article we saw how to expose and consume an Odata endpoint in a Web API 2 application. I hope you have understood it and liked. Thanks, happy learning.