An OData V4 Endpoint With ASP.NET Web API 2.2

In this article you will learn about an OData v4 Endpoint with ASP.NET Web API 2.2.

Introduction

OData (Open Data Protocol) is an open protocol for sharing the data. It is OASIS (Organization for the Advancement of Structured Information Standards) standard which defines best practice for building and consuming REST API.

In this article we learn how to create OData services using ASP.NET Web API. Here, I am not using entity framework as data access. I am just using in-memory data as a data source.

The following steps are required to perform to use OData with Web API.

Step 1: Create Web API solution and install OData for Asp.NET,

First step is to create empty solution for Web API and installed ASP.NET OData using the following command,

console

Step 2: Create model class

Create model class which is used in communication.

  1. public class TestData  
  2. {  
  3.     public int Id { getset; }  
  4.     public string Name { getset; }  
  5.     public string Role { getset; }  
  6. }  
Step 3: Create In-memory data source

When we use OData service with Web API, Entity Framework is best suited. This is quite complex in demo project. So here I am using in-memory data source and it is very simple and straightforward. In data source, I have created some data and return the list.
  1. public List<TestData> CreateTestData()  
  2. {  
  3.     List<TestData> data = new List<TestData>();  
  4.     data.Add(new TestData { Id = 1, Name = "Jignesh", Role = "Project Manager" });  
  5.     data.Add(new TestData { Id = 2, Name = "Tejas", Role = "Architect" });  
  6.     data.Add(new TestData { Id = 3, Name = "Rakesh", Role = "Lead" });  
  7.   
  8.     return data;  
  9. }  
Step 4: Define Controller

Next step is to define controller. Controller class is needed to inherit from ODataController and base class of ODataController is ApiController. ODataController class has methods for reading and writing data using OData format.

EnableQuery Attribute class enables querying using OData query syntax. This attribute is responsible to validate all incoming queries so that we can avoid processing malicious queries.

The body of controller, I have defined Get method that returns value from in-memory data source.
  1. public class TestDataController : ODataController  
  2. {  
  3.     [EnableQuery]  
  4.     public IHttpActionResult Get()  
  5.     {  
  6.         var result = CreateTestData().AsQueryable();  
  7.         return Ok(result);  
  8.     }  
  9. }  
Step 5: Configure the Endpoint

The final step is to define the end point. Endpoint configured in WebApiConfig.cs file under App_Start. Configuration code contains two things,
  • Create EDM (Entity Data Model)
  • Adding Route

The Entity Data Model is used to create service Meta. The ODataConventionModelBuilder is used to create an EDM. if we required more control on EDM than we can use ODataModelBuilder class to create the EDM. MapODataServiceRoute extension is used to define OData v4 route. Point to remember, application has multiple OData endpoints then create separate route for each.

  1. namespace WebAPITest  
  2. {  
  3.     using Microsoft.OData.Edm;  
  4.     using System.Web.Http;  
  5.     using System.Web.OData.Batch;  
  6.     using System.Web.OData.Builder;  
  7.     using System.Web.OData.Extensions;  
  8.     public static class WebApiConfig  
  9.     {  
  10.         public static void Register(HttpConfiguration config)  
  11.         {  
  12.             config.MapODataServiceRoute("odata"null, GetEdmModel(), new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));  
  13.             config.EnsureInitialized();  
  14.   
  15.         }  
  16.         private static IEdmModel GetEdmModel()  
  17.         {  
  18.             ODataConventionModelBuilder builder = new ODataConventionModelBuilder();  
  19.             builder.Namespace = "WebAPITest";  
  20.             builder.ContainerName = "DefaultContainer";  
  21.             builder.EntitySet<TestData>("TestData");  
  22.             var edmModel = builder.GetEdmModel();  
  23.             return edmModel;  
  24.         }  
  25.     }  
  26. }  
Service Testing

In preceding example, I have defined the GET method in controller. To test OData service, we can use fiddler. Here I have shared some test URL and result as following.

Get Service document

URL:
http://localhost:24367/

Result:
  1. {  
  2.   "@odata.context":"http://localhost:24367/$metadata","value":[  
  3.     {    
  4.                 "name":"TestData","kind":"EntitySet","url":"TestData"  
  5.     }  
  6.   ]  
  7. }  
Get Service metadata

URL:
http://localhost:24367/$metadata

Result:

result

Queries on data source

Get All Test data:

URL:
http://localhost:24367/TestData

Result:
  1. {  
  2.   "@odata.context":"http://localhost:24367/$metadata#TestData","value":[  
  3.     { "Id":1,"Name":"Jignesh","Role":"Project Manager"   },  
  4.     { "Id":2,"Name":"Tejas","Role":"Architect" },  
  5.     {  "Id":3,"Name":"Rakesh","Role":"Lead" }  
  6.   ]  
  7. }  
Select only Name filed from source:

URL:
http://localhost:24367/TestData?$Select=Name

Result:
  1. {  
  2.   "@odata.context":"http://localhost:24367/$metadata#TestData(Name)","value":[  
  3.     { "Name":"Jignesh"},{"Name":"Tejas"},{"Name":"Rakesh"}  
  4.   ]  
  5. }  
Filter by Role:

URL:
http://localhost:24367/TestData?$filter=contains(Role,'Ar')

Result:
  1. {  
  2.   "@odata.context":"http://localhost:24367/$metadata#TestData","value":[  
  3.     { "Id":2,"Name":"Tejas","Role":"Architect" }  
  4.   ]  
  5. }  
Filter by Name:

URL:
http://localhost:24367/TestData?$filter=Name eq 'Jignesh'

Result:
  1. {  
  2.   "@odata.context":"http://localhost:24367/$metadata#TestData","value":[  
  3.     {      "Id":1,"Name":"Jignesh","Role":"Project Manager"    }  
  4.   ]  
  5. }  
Summary

OData has now become standard way to share the data between two application software. In this article we learnt, how to use create OData endpoint in Web API. Hope this will help you.

Read more articles on ASP.NET: