The Open Data Protocol (OData) is a protocol to request data through a query string.

The Open Data Protocol (OData) is a protocol to access data on the web. It provides a uniform way to query and manipulate data sets through CRUD operations.

This article shows how to create an OData v4 endpoint that supports Get operations.

This article has two sections:

Why we need an OData Service?

Advantages

  1. OData is based on RESTful architecture, so we can retrieve data based on an URL query string.

  2. OData supports HTTP, Atom Pub as well as JSON format.

  3. It is very lightweight to use. Since it is lightweight, the performance is very good while interacting between client and service.

  4. It supports for any type of data source. Even you can use your own custom class as a data source.

  5. You can create your own custom methods and expose it.

  6. It supports different HTTP methods:

    1. GET: Gets one or many entries.
    2. POST: Create a new entry.
    3. PUT: Update an existing entry.
    4. DELETE: Remove an entry.

Limitations

  1. It is much less secure as it is purely URL based.
  2. As per my understanding, OData does not support every query operator in LINQ like Filter, Skip, Take etc.

Create the Visual Studio Project

In Visual Studio, from the File menu, select New > Project.

Expand Installed > Templates > Visual C# > Web, and select the ASP.NET Web Application template. Name the project "ODataServiceApp".

Web Application template

In the New Project dialog, select the Empty template. Click Web APIcheckbox. Click OK.

Application template

Install the OData Packages


OData Packages

From the Tools menu, select NuGet Package Manager > Package Manager Console. Run the following command in the Package Manager Console.

PM> Install-Package Microsoft.AspNet.OData

This command installs the latest OData NuGet packages.

Note: You can install OData either from Package Manager Console or Package Manager Console for Solution.

Add Model Classes

A model is a class that contains data entity in the application.

In Solution Explorer, Right-click the Model folder. From the context menu, select Add > Class.

Model

Add two model class Course.cs and Subject.cs under Model folder.

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.ComponentModel.DataAnnotations;
  6. namespace ODataServiceApp.Models
  7. {
  8. publicclassCourse
  9. {
  10. [Key]
  11. publicString ID
  12. {
  13. get;
  14. set;
  15. }
  16. [Required]
  17. publicString Name
  18. {
  19. get;
  20. set;
  21. }
  22. publicString Description
  23. {
  24. get;
  25. set;
  26. }
  27. publicList < Subject > Subjects
  28. {
  29. get;
  30. set;
  31. }
  32. }
  33. }
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.DataAnnotations;
  4. using System.Linq;
  5. using System.Web;
  6. namespace ODataServiceApp.Models
  7. {
  8. publicclassSubject
  9. {
  10. [Key]
  11. publicString ID
  12. {
  13. get;
  14. set;
  15. }
  16. [Required]
  17. publicString Name
  18. {
  19. get;
  20. set;
  21. }
  22. }
  23. }
The attributes [Key] and [Required] are all from. System.ComponentModel.DataAnnotations.

Inline data source

This example uses inline data sources. The below steps describe how to to create the inline data source.

Add a folder DataSource and add a class with name SampleDataSources.cs with the code below:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using ODataServiceApp.Models;
  6. namespace ODataServiceApp.DataSource
  7. {
  8. publicclassDemoDataSources
  9. {
  10. privatestaticDemoDataSources instance
  11. = null;
  12. publicstaticDemoDataSources Instance
  13. {
  14. get
  15. {
  16. if (instance == null)
  17. {
  18. instance = newDemoDataSources();
  19. }
  20. return instance;
  21. }
  22. }
  23. publicList < Course > Courses
  24. {
  25. get;
  26. set;
  27. }
  28. publicList < Subject > Subjects
  29. {
  30. get;
  31. set;
  32. }
  33. private DemoDataSources()
  34. {
  35. this.Reset();
  36. this.Initialize();
  37. }
  38. publicvoid Reset()
  39. {
  40. this.Courses = newList < Course >
  41. ();
  42. this.Subjects = newList < Subject >
  43. ();
  44. }
  45. publicvoid Initialize()
  46. {
  47. this.Subjects.AddRange(newList <
  48. Subject > ()
  49. {
  50. newSubject()
  51. {
  52. ID = "0",
  53. Name = "C"
  54. },
  55. newSubject()
  56. {
  57. ID = "1",
  58. Name = "C++"
  59. },
  60. newSubject()
  61. {
  62. ID = "2",
  63. Name = "Data Structure"
  64. },
  65. newSubject()
  66. {
  67. ID = "3",
  68. Name = ".Net"
  69. }
  70. });
  71. this.Courses.AddRange(newList <
  72. Course >
  73. {
  74. newCourse()
  75. {
  76. ID = "001",
  77. Name = "MCA",
  78. Subjects = newList < Subject >
  79. {
  80. Subjects[0],
  81. Subjects[1]
  82. },
  83. Description =
  84. "Master of Computer Application"
  85. },
  86. newCourse()
  87. {
  88. ID = "002",
  89. Name = "MBA",
  90. Description =
  91. "Master of Business Application",
  92. Subjects = newList < Subject >
  93. {
  94. Subjects[2],
  95. Subjects[3]
  96. }
  97. },
  98. newCourse()
  99. {
  100. ID = "003",
  101. Name = "CA",
  102. Description =
  103. "Chartered Accountant",
  104. },
  105. newCourse()
  106. {
  107. ID = "004",
  108. Name = "MA"
  109. }
  110. });
  111. }
  112. }
  113. }
Add Controllers

Add two controller classes under the folder Controllers

First is controller for Courses,

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. using ODataServiceApp.DataSource;
  7. using System.Web.Http;
  8. using System.Web.OData;
  9. namespace ODataServiceApp.Controllers
  10. {
  11. [EnableQuery]
  12. publicclassCourseController:
  13. ODataController
  14. {
  15. publicIHttpActionResult Get()
  16. {
  17. return Ok(DemoDataSources.Instance
  18. .Courses.AsQueryable());
  19. }
  20. }
  21. }
2nd controller for Subjects,
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. using ODataServiceApp.DataSource;
  7. using System.Web.Http;
  8. using System.Web.OData;
  9. namespace ODataServiceApp.Controllers
  10. {
  11. [EnableQuery]
  12. publicclassSubjectsController:
  13. ODataController
  14. {
  15. publicIHttpActionResult Get()
  16. {
  17. return Ok(DemoDataSources.Instance
  18. .Subjects.AsQueryable());
  19. }
  20. }
  21. }
Configure the Endpoint

Modify the WebApiConfig.cs file under App_Startto configure the Endpoints.
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web.Http;
  5. using ODataServiceApp.Models;
  6. using Microsoft.OData.Edm;
  7. using System.Web.OData.Batch;
  8. using System.Web.OData.Builder;
  9. using System.Web.OData.Extensions;
  10. namespace ODataServiceApp
  11. {
  12. publicstaticclassWebApiConfig
  13. {
  14. publicstaticvoid Register(
  15. HttpConfiguration config)
  16. {
  17. config.MapODataServiceRoute("odata",
  18. null, GetEdmModel(),
  19. newDefaultODataBatchHandler(
  20. GlobalConfiguration.DefaultServer
  21. ));
  22. config.EnsureInitialized();
  23. }
  24. privatestaticIEdmModel GetEdmModel()
  25. {
  26. ODataConventionModelBuilder builder
  27. = newODataConventionModelBuilder();
  28. builder.Namespace =
  29. "ODataServiceApp";
  30. builder.ContainerName =
  31. "DefaultContainer";
  32. builder.EntitySet < Course > (
  33. "Courses");
  34. builder.EntitySet < Subject > (
  35. "Subjects");
  36. var edmModel = builder.GetEdmModel();
  37. return edmModel;
  38. }
  39. }
  40. }
Below URLs to call GET methods.

OData service creation is completed and now it’s time to consume it. It can be consumed in different ways; either using web application or web site etc. Scripting languages or frameworks can be used to consume the OData services. In the below example, websiteandAngularJS framework are used to consume OData service.

Consuming OData service Get methods

Steps to consume OData service Get methods

In Visual Studio, from the File menu, select New > Web Site.

Expand Installed > Templates > Visual C# > Web, and select the ASP.NET Empty Web Site template. Name the project "ODataWebAppClient".

ASP.NET Empty Web

In Solution Explorer, Right-click and select Add > HTML Page and name it as “Index.html”.

HTML Page

Index.htmlwith the code below:

  1. <!DOCTYPEhtml>
  2. <html>
  3. <head>
  4. <title></title>
  5. <metacharset="utf-8" />
  6. <linkrel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
  7. <scriptsrc="//code.jquery.com/jquery-2.1.3.min.js">
  8. </script>
  9. <scriptsrc="//ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js">
  10. </script>
  11. <scriptsrc="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap.min.js">
  12. </script>
  13. <scripttype="text/javascript">
  14. 'use strict'; var app = angular.module('OData',
  15. []); app.controller("ODataController",
  16. ['$scope', '$http', function ($scope,
  17. $http) { $scope.SubjectList = []; $scope.GetSubjectList
  18. = function () { $http({ method: 'GET',
  19. url: "http://localhost:52766/Subjects?$filter=contains(Name,'Structure')",
  20. async: true, cache: true, headers:
  21. { 'Content-Type': "application/json;
  22. charset=utf-8" } }) .success(function
  23. (data) { $scope.SubjectList = data.value;
  24. }) .error(function (data, status, headers,
  25. config) { alert(data.error.trim());
  26. }) }; $scope.GetSubjectList(); }]);
  27. </script>
  28. </head>
  29. <bodyng-app="OData" class="container">
  30. <divng-controller="ODataController" ng-class="row">
  31. <tableclass="table table-striped">
  32. <thead>
  33. <tr>
  34. <th>ID</th>
  35. <th>Name</th>
  36. </tr>
  37. </thead>
  38. <tbody>
  39. <trng-repeat="iteminSubjectList">
  40. <td>{{item.ID}}</td>
  41. <td>{{item.Name}}</td>
  42. </tr>
  43. </tbody>
  44. </table>
  45. </div>
  46. </body>
  47. </html>
Below CSS and scripts from CDN are used for the above example:
  1. <linkrel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
  2. <scriptsrc="//code.jquery.com/jquery-2.1.3.min.js">
  3. </script>
  4. <scriptsrc="//ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js">
  5. </script>
  6. <scriptsrc="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap.min.js">
  7. </script>
Output:

Output