{"id":75928,"date":"2022-10-24T08:00:09","date_gmt":"2022-10-24T06:00:09","guid":{"rendered":"https:\/\/drafts.code-maze.com\/?p=75797"},"modified":"2024-01-31T15:16:59","modified_gmt":"2024-01-31T14:16:59","slug":"aspnetcore-webapi-using-odata","status":"publish","type":"post","link":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/","title":{"rendered":"Using OData with ASP.NET Core Web API"},"content":{"rendered":"<p>In this article, we will learn how to use OData with ASP.NET Core Web API services.<\/p>\n<p>OData (Open Data Protocol) is an open protocol that defines a set of best practices for building and consuming RESTful APIs. Initiated by Microsoft in 2007, it has become an OASIS standard and has been approved by ISO\/IEC. Currently, OData is in version 4.\u00a0<\/p>\n<div style=\"padding: 20px; border-left: 5px #dc2323 solid; display: block; margin-bottom: 20px; box-shadow: 1px 1px 5px 0px lightgrey;\">To download the source code for this article, you can visit our <a href=\"https:\/\/github.com\/CodeMazeBlog\/CodeMazeGuides\/tree\/main\/aspnetcore-webapi\/UsingOData\" target=\"_blank\" rel=\"nofollow noopener\">GitHub repository<\/a>.<\/div>\n<p>Let&#8217;s start.<\/p>\n<h2>Introduction to OData<\/h2>\n<p>OData follows common practices for building RESTful web services. For instance, it uses URLs to identify resources and HTTP verbs like GET, POST, etc. to define operations on them. Data exposed by the OData service is described by an Entity Data Model (EDM), while JSON or AtomPub are used for message encoding.<\/p>\n<p>OData can be compared with <a href=\"https:\/\/code-maze.com\/graphql-asp-net-core-tutorial\/\" target=\"_blank\" rel=\"noopener\">GraphQL<\/a> as both standards can be used for API development. OData is simpler and easier to understand, but less powerful than GraphQL. Since it is based on REST, it is easier to pick up and create or migrate existing APIs, while GraphQL will need a lot of work to make it work for our API.<\/p>\n<p>Let&#8217;s consider the case where we are building a web service that provides information on companies and their products. In order to request a resource using OData we can send a simple GET request to the web service:<\/p>\n<p><code>GET \/odata\/companies<\/code><\/p>\n<p>This will get us all the available entries. We can also query for a specific entry, by providing its ID:<\/p>\n<p><code>GET \/odata\/companies(23)<\/code><\/p>\n<p>Moreover, we may send query options to the web service, in the same way, that we send query string parameters in GET requests:<\/p>\n<p><code>GET \/odata\/companies?$top=5&amp;$skip=10<\/code><\/p>\n<p>Here we request the top 5 results, after skipping the first 10 entries. Note that all options in OData start with the dollar sign ($) and that they can be combined in the same query.<\/p>\n<p>Here is a list of the query options available in OData:<\/p>\n<ul>\n<li><code>\/odata\/companies?$top=5<\/code>\u00a0 &#8211;\u00a0 \u00a0Get the top 5 entries<\/li>\n<li><code>\/odata\/companies?$count=true<\/code>\u00a0 \u00a0&#8211;\u00a0 \u00a0Get the total entry count (along with all the entries)<\/li>\n<li>\/<code>odata\/companies?$filter=city eq \u2018New York\u2019<\/code>\u00a0 \u00a0&#8211;\u00a0 \u00a0Get entries where city=\u2019New York\u2019<\/li>\n<li><code>\/odata\/companies?$filter=contains(city, 'York')<\/code>\u00a0 \u00a0&#8211;\u00a0 \u00a0Get entries where the city contains \u2018York\u2019<\/li>\n<li><code>\/odata\/companies?$orderby=Name<\/code>\u00a0 \u00a0&#8211;\u00a0 \u00a0Order entries by company name<\/li>\n<li><code>\/odata\/companies?$skip=5<\/code>\u00a0 \u00a0&#8211;\u00a0 \u00a0Skip the five first entries and return the rest<\/li>\n<li><code>\/odata\/companies?$select=ID,Name<\/code>\u00a0 \u00a0&#8211;\u00a0 \u00a0Return only the ID and Name of all companies<\/li>\n<li><code>\/odata\/companies?$expand=Products<\/code>\u00a0 \u00a0&#8211;\u00a0 \u00a0Include also the products produced by the companies<\/li>\n<\/ul>\n<p>OData can also be used for the creation, update, or deletion of resources using POST, PUT or DELETE requests respectively.<\/p>\n<h2>Prepare ASP.NET Core Web API Project<\/h2>\n<p>Microsoft provides support for the OData standard (currently at version 4), with the <code>Microsoft.AspNetCore.OData<\/code> package(currently at version 8.0.11).<\/p>\n<p>For this article, we will implement the above-mentioned scenario and create a web service that uses OData with ASP.NET Core Web API to create an endpoint for data on companies and products.<\/p>\n<h3>The Model<\/h3>\n<p>First, we define our model:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class Company\r\n{\r\n    public int ID { get; set; }\r\n    public string? Name { get; set; }\r\n    public int Size { get; set; }\r\n    public List&lt;Product&gt;? Products { get; set; }\r\n}\r\n<\/pre>\n<p>Each company provides a range of products:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class Product\r\n{\r\n    public int ID { get; set; }\r\n    public int CompanyID { get; set; }\r\n    public string? Name { get; set; }\r\n    public decimal Price { get; set; }\r\n}<\/pre>\n<p>We will use the in-memory database for this article. For that, we are going to implement the Context class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class ApiContext: DbContext\r\n{\r\n    public ApiContext(DbContextOptions&lt;ApiContext&gt; options)\r\n        : base(options)\r\n    {\r\n    }\r\n\r\n    public DbSet&lt;Company&gt; Companies { get; set; }\r\n    public DbSet&lt;Product&gt; Products { get; set; }\r\n}<\/pre>\n<p>We also create a simplified repository class that will handle the interactions with the database:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class CompanyRepo : ICompanyRepo\r\n{\r\n    private readonly ApiContext _context;\r\n    public CompanyRepo(ApiContext context)\r\n    {\r\n        _context = context;\r\n    }\r\n\r\n    public IQueryable&lt;Company&gt; GetAll()\r\n    {\r\n        return _context.Companies\r\n            .Include(a =&gt; a.Products)\r\n            .AsQueryable();\r\n    }\r\n\r\n    public IQueryable&lt;Company&gt; GetById(int id)\r\n    {\r\n        return _context.Companies\r\n            .Include(a =&gt; a.Products)\r\n            .AsQueryable()\r\n            .Where(c =&gt; c.ID == id);\r\n    }\r\n\r\n    public void Create(Company company)\r\n    {\r\n        _context.Companies\r\n            .Add(company);\r\n        _context.SaveChanges();\r\n    }\r\n\r\n    public void Update(Company company)\r\n    {\r\n        _context.Companies\r\n            .Update(company);\r\n        _context.SaveChanges();\r\n    }\r\n\r\n    public void Delete(Company company)\r\n    {\r\n        _context.Companies\r\n            .Remove(company);\r\n        _context.SaveChanges();\r\n    }\r\n}\r\n<\/pre>\n<p>The <code>CompanyRepo<\/code> class implements the <code>ICompanyRepo<\/code> interface:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public interface ICompanyRepo\r\n{\r\n    public IQueryable&lt;Company&gt; GetAll();\r\n    public IQueryable&lt;Company&gt; GetById(int id);\r\n    public void Create(Company company);\r\n    public void Update(Company company);\r\n    public void Delete(Company company);\r\n}<\/pre>\n<p>Note that both our <code>GetXXX()<\/code> methods return a reference to <code>IQueryable&lt;Company&gt;<\/code>. OData will use this interface to perform queries on company data.<\/p>\n<h2>Using OData With ASP.NET Core Web API<\/h2>\n<p>Now, we proceed with creating our controller. The controller seems like a usual RESTful controller and actually, it can work like one. This means that we can send a GET request to <code>\/api\/companies<\/code> and receive a list of all companies in the repository.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[Route(\"api\/[controller]\")]\r\n[ApiController]\r\npublic class CompaniesController : ControllerBase\r\n{\r\n    private readonly ICompanyRepo _repo;\r\n    public CompaniesController(ICompanyRepo repo)\r\n    {\r\n        _repo = repo;\r\n    }\r\n\r\n    ...\r\n}\r\n<\/pre>\n<h3>GET requests<\/h3>\n<p>The power of OData lies mainly in the functionality that it offers for performing queries. Therefore, the GET requests are the most interesting part of OData. In the controller, we implement two types of GET requests:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[EnableQuery(PageSize = 3)]\r\n[HttpGet]\r\npublic IQueryable&lt;Company&gt; Get()\r\n{\r\n    return _repo.GetAll();\r\n}\r\n\r\n[EnableQuery]\r\n[HttpGet(\"{id}\")]\r\npublic SingleResult&lt;Company&gt; Get([FromODataUri] int key)\r\n{\r\n    return SingleResult.Create(_repo.GetById(key));\r\n}<\/pre>\n<p>In order to enable OData, we do three things:<\/p>\n<ul>\n<li>Annotate the respective methods with the <code>[EnableQuery]<\/code> attribute<\/li>\n<li>Made the first method return an <code>IQueryable<\/code> reference to the company list<\/li>\n<li>Made the second method return a <code>SingleResult<\/code> reference to the selected item in the company list<\/li>\n<\/ul>\n<p>The <code>[EnableQuery]<\/code> attribute enables clients to send queries, by using query options such as $filter, $sort, and $page. By using <code>IQueryable<\/code>, OData will be able to query the list in various ways. Note that we can also define a default page size (3) for each request.<\/p>\n<p>You should pay special care to the second method: if you define the method input parameter with a name other than <code>key<\/code> then this method will not work!<\/p>\n<h3>POST\/PUT\/DELETE Requests With OData and ASP.NET Core Web API<\/h3>\n<p>We can support all CRUD requests with OData, by adding the respective methods in the companies controller. The POST request inserts a new company into the database:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[HttpPost]\r\npublic IActionResult Post([FromBody] Company company)\r\n{\r\n    if (!ModelState.IsValid)\r\n    {\r\n        return BadRequest(ModelState);\r\n    }\r\n    _repo.Create(company);\r\n\r\n    return Created(\"companies\", company);\r\n}\r\n<\/pre>\n<p>With the PUT request, we can update an entry:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[HttpPut]\r\npublic IActionResult Put([FromODataUri] int key, [FromBody] Company company)\r\n{\r\n    if (!ModelState.IsValid)\r\n    {\r\n        return BadRequest(ModelState);\r\n    }\r\n\r\n    if (key != company.ID)\r\n    {\r\n        return BadRequest();\r\n    }\r\n\r\n    _repo.Update(company);\r\n\r\n    return NoContent();\r\n}<\/pre>\n<p>Finally, we can delete a company from the database, by using the DELETE method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[HttpDelete]\r\npublic IActionResult Delete([FromODataUri] int key)\r\n{\r\n    var company = _repo.GetById(key);\r\n    if (company is null)\r\n    {\r\n        return BadRequest();\r\n    }\r\n\r\n    _repo.Delete(company.First());\r\n\r\n    return NoContent();\r\n}<\/pre>\n<h3>OData Setup<\/h3>\n<p>Finally, we have to register OData in <code>Program.cs<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">static IEdmModel GetEdmModel()\r\n{\r\n    ODataConventionModelBuilder builder = new();\r\n    builder.EntitySet&lt;Company&gt;(\"Companies\");\r\n    return builder.GetEdmModel();\r\n}\r\n\r\nvar builder = WebApplication.CreateBuilder(args);\r\n\r\nbuilder.Services.AddControllers()\r\n    .AddOData(options =&gt; options\r\n        .AddRouteComponents(\"odata\", GetEdmModel())\r\n        .Select()\r\n        .Filter()\r\n        .OrderBy()\r\n        .SetMaxTop(20)\r\n        .Count()\r\n        .Expand()\r\n    );\r\n\r\nbuilder.Services.AddDbContext&lt;ApiContext&gt;(opt =&gt; opt.UseInMemoryDatabase(databaseName: \"CompaniesDB\"));\r\nbuilder.Services.AddScoped&lt;ICompanyRepo, CompanyRepo&gt;();\r\nvar app = builder.Build();\r\nDBSeeder.AddCompaniesData(app);\r\n\r\n...<\/pre>\n<p>We register Oda with the <code>AddOData()<\/code> method, where we also define a number of options regarding the capabilities of our web service. Here, we create an OData endpoint that will:<\/p>\n<ul>\n<li>contain \u201c<code>odata<\/code>\u201d in the URL (instead of\u00a0 the usual \u201c<code>api<\/code>\u201d)<\/li>\n<li>enable selection, filtering, ordering, counting, and expansion functionality<\/li>\n<li>return up to 20 entries at each request<\/li>\n<\/ul>\n<p>The <code>AddOData()<\/code> method uses the <code>GetEdmModel()<\/code>method that returns the data model, which is the basis of an OData service. The OData service uses an abstract data model called Entity Data Model (EDM) to describe the exposed data in the service. The <code>ODataConventionModelBuilder<\/code> class creates an EDM by using a set of default naming conventions EDM, an approach that requires the least code. We can use the <code>ODataModelBuilder<\/code> class to create the EDM if we want more control over the EDM.<\/p>\n<p>We should pay attention to the <code>EntitySet<\/code> method: we should provide the exact name of the controller (<code>Companies<\/code>) as its parameter. If we use a different name for the entity set (e.g. <code>Company<\/code> instead of <code>Companies<\/code>), then OData will not work.<\/p>\n<p>Finally, in order to seed the in-memory database, we run the <code>AddCompaniesData()<\/code> static method, which we define in a separate class (<code>DBSeeder.cs<\/code>):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class DBSeeder\r\n{\r\n    public static void AddCompaniesData(WebApplication app)\r\n    {\r\n        var scope = app.Services.CreateScope();\r\n        var db = scope.ServiceProvider.GetService&lt;ApiContext&gt;();\r\n\r\n        db.Companies.Add(\r\n            new Company()\r\n            {\r\n                ID = 1,\r\n                Name = \"Company A\",\r\n                Size = 25\r\n            });\r\n\r\n        \/\/more companies here...\r\n        \r\n        db.Products.Add(\r\n            new Product()\r\n            {\r\n                ID = 1,\r\n                CompanyID = 1,\r\n                Name = \"Product A\",\r\n                Price = 10\r\n            });\r\n\r\n        \/\/more products here..\r\n\r\n        db.SaveChanges();\r\n    }\r\n}<\/pre>\n<p>Now, we are ready to run our OData service and test the API!<\/p>\n<h2>Testing the API<\/h2>\n<p>Using Postman, or a web browser, we can send a GET request to our web service: <code>\/odata\/companies?$filter=Size gt 20&amp;$count=true<\/code>.<\/p>\n<p>After we do that, we can inspect the returned JSON payload as a result:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\">{\r\n  \"@odata.context\": \"https:\/\/localhost:7004\/odata\/$metadata#Companies\",\r\n  \"@odata.count\": 3,\r\n  \"value\": [\r\n    {\r\n      \"ID\": 1,\r\n      \"Name\": \"Company A\",\r\n      \"Size\": 25\r\n    },\r\n    {\r\n      \"ID\": 2,\r\n      \"Name\": \"Company B\",\r\n      \"Size\": 56\r\n    },\r\n    {\r\n      \"ID\": 4,\r\n      \"Name\": \"Company D\",\r\n      \"Size\": 205\r\n    }\r\n  ]\r\n}<\/pre>\n<p>We see that the companies&#8217; data returned by OData do not contain any information about their respective products. In order to get the products too, we additionally need to send the $expand option: <code>\/odata\/companies?$filter=Size gt 20&amp;$count=true&amp;$expand=Products<\/code>.<\/p>\n<p>The results now contain also information about products:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\">{\r\n  \"@odata.context\": \"https:\/\/localhost:7004\/odata\/$metadata#Companies(Products())\",\r\n  \"@odata.count\": 3,\r\n  \"value\": [\r\n    {\r\n      \"ID\": 1,\r\n      \"Name\": \"Company A\",\r\n      \"Size\": 25,\r\n      \"Products\": [\r\n        {\r\n          \"ID\": 1,\r\n          \"Name\": \"Product A\",\r\n          \"Price\": 10\r\n        },\r\n        {\r\n          \"ID\": 2,\r\n          \"Name\": \"Product B\",\r\n          \"Price\": 35\r\n        }\r\n      ]\r\n    },\r\n    \r\n    \/\/ --&gt; more companies and products here\r\n  ]\r\n}<\/pre>\n<p>Next, we create a new company by sending a POST request to URL <code>\/odata\/companies<\/code> with the body:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\">{\r\n    \"ID\": 10,\r\n    \"Name\": \"Company Z\",\r\n    \"Size\": 100\r\n}<\/pre>\n<p>The returned response contains the newly created object:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\">{\r\n    \"@odata.context\": \"https:\/\/localhost:7004\/odata\/$metadata#Companies\/$entity\",\r\n    \"ID\": 10,\r\n    \"Name\": \"Company Z\",\r\n    \"Size\": 100\r\n}<\/pre>\n<p>We can also modify an existing entry (the one with ID=1) by sending a PUT request to the URL <code>\/odata\/companies(1)<\/code> with the body:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\">{\r\n    \"ID\": 1,\r\n    \"Name\": \"Company A\",\r\n    \"Size\": 350\r\n}<\/pre>\n<p>Finally, we may delete an entry (again with ID=1) by sending a DELETE request to the URL <code>\/odata\/companies(1)<\/code>. Both PUT and DELETE methods return a <code>204 No Content<\/code> response.<\/p>\n<h2>Conclusion<\/h2>\n<p>In this article, we have learned how to incorporate the OData standard in our ASP.NET Core projects, in order to create web APIs with extensive querying capabilities.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we will learn how to use OData with ASP.NET Core Web API services. OData (Open Data Protocol) is an open protocol that defines a set of best practices for building and consuming RESTful APIs. Initiated by Microsoft in 2007, it has become an OASIS standard and has been approved by ISO\/IEC. Currently, [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":62187,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[2079],"tags":[79,122,121,1465,57,58,130],"class_list":["post-75928","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-api","tag-asp-net-core","tag-delete","tag-get","tag-odata","tag-post","tag-put","tag-web-api","et-has-post-format-content","et_post_format-et-post-format-standard"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using OData with ASP.NET Core Web API - Code Maze<\/title>\n<meta name=\"description\" content=\"In this article, we will learn how to implement support for the OData standard in our ASP.NET Core Web API services.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using OData with ASP.NET Core Web API - Code Maze\" \/>\n<meta property=\"og:description\" content=\"In this article, we will learn how to implement support for the OData standard in our ASP.NET Core Web API services.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/\" \/>\n<meta property=\"og:site_name\" content=\"Code Maze\" \/>\n<meta property=\"article:published_time\" content=\"2022-10-24T06:00:09+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-31T14:16:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1100\" \/>\n\t<meta property=\"og:image:height\" content=\"620\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Code Maze\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/CodeMazeBlog\" \/>\n<meta name=\"twitter:site\" content=\"@CodeMazeBlog\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Code Maze\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/\"},\"author\":{\"name\":\"Code Maze\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04\"},\"headline\":\"Using OData with ASP.NET Core Web API\",\"datePublished\":\"2022-10-24T06:00:09+00:00\",\"dateModified\":\"2024-01-31T14:16:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/\"},\"wordCount\":1185,\"commentCount\":6,\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"keywords\":[\"asp.net core\",\"DELETE\",\"GET\",\"OData\",\"POST\",\"PUT\",\"Web API\"],\"articleSection\":[\"Web API\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/\",\"url\":\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/\",\"name\":\"Using OData with ASP.NET Core Web API - Code Maze\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"datePublished\":\"2022-10-24T06:00:09+00:00\",\"dateModified\":\"2024-01-31T14:16:59+00:00\",\"description\":\"In this article, we will learn how to implement support for the OData standard in our ASP.NET Core Web API services.\",\"breadcrumb\":{\"@id\":\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#primaryimage\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"width\":1100,\"height\":620,\"caption\":\"ASP.NET Core\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/code-maze.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using OData with ASP.NET Core Web API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/code-maze.com\/#website\",\"url\":\"https:\/\/code-maze.com\/\",\"name\":\"Code Maze\",\"description\":\"Learn. Code. Succeed.\",\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/code-maze.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/code-maze.com\/#organization\",\"name\":\"Code Maze\",\"url\":\"https:\/\/code-maze.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"width\":3511,\"height\":3510,\"caption\":\"Code Maze\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/CodeMazeBlog\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04\",\"name\":\"Code Maze\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png\",\"caption\":\"Code Maze\"},\"description\":\"This is the standard author on the site. Most articles are published by individual authors, with their profiles, but when several authors have contributed, we publish collectively as a part of this profile.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/codemaze\/\",\"https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog\"],\"url\":\"https:\/\/code-maze.com\/author\/codemazecontributor\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using OData with ASP.NET Core Web API - Code Maze","description":"In this article, we will learn how to implement support for the OData standard in our ASP.NET Core Web API services.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/","og_locale":"en_US","og_type":"article","og_title":"Using OData with ASP.NET Core Web API - Code Maze","og_description":"In this article, we will learn how to implement support for the OData standard in our ASP.NET Core Web API services.","og_url":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/","og_site_name":"Code Maze","article_published_time":"2022-10-24T06:00:09+00:00","article_modified_time":"2024-01-31T14:16:59+00:00","og_image":[{"width":1100,"height":620,"url":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","type":"image\/png"}],"author":"Code Maze","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/CodeMazeBlog","twitter_site":"@CodeMazeBlog","twitter_misc":{"Written by":"Code Maze","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#article","isPartOf":{"@id":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/"},"author":{"name":"Code Maze","@id":"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04"},"headline":"Using OData with ASP.NET Core Web API","datePublished":"2022-10-24T06:00:09+00:00","dateModified":"2024-01-31T14:16:59+00:00","mainEntityOfPage":{"@id":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/"},"wordCount":1185,"commentCount":6,"publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"image":{"@id":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","keywords":["asp.net core","DELETE","GET","OData","POST","PUT","Web API"],"articleSection":["Web API"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/","url":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/","name":"Using OData with ASP.NET Core Web API - Code Maze","isPartOf":{"@id":"https:\/\/code-maze.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#primaryimage"},"image":{"@id":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","datePublished":"2022-10-24T06:00:09+00:00","dateModified":"2024-01-31T14:16:59+00:00","description":"In this article, we will learn how to implement support for the OData standard in our ASP.NET Core Web API services.","breadcrumb":{"@id":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#primaryimage","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","width":1100,"height":620,"caption":"ASP.NET Core"},{"@type":"BreadcrumbList","@id":"https:\/\/code-maze.com\/aspnetcore-webapi-using-odata\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/code-maze.com\/"},{"@type":"ListItem","position":2,"name":"Using OData with ASP.NET Core Web API"}]},{"@type":"WebSite","@id":"https:\/\/code-maze.com\/#website","url":"https:\/\/code-maze.com\/","name":"Code Maze","description":"Learn. Code. Succeed.","publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/code-maze.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/code-maze.com\/#organization","name":"Code Maze","url":"https:\/\/code-maze.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","width":3511,"height":3510,"caption":"Code Maze"},"image":{"@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/CodeMazeBlog"]},{"@type":"Person","@id":"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04","name":"Code Maze","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/person\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png","caption":"Code Maze"},"description":"This is the standard author on the site. Most articles are published by individual authors, with their profiles, but when several authors have contributed, we publish collectively as a part of this profile.","sameAs":["https:\/\/www.linkedin.com\/company\/codemaze\/","https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog"],"url":"https:\/\/code-maze.com\/author\/codemazecontributor\/"}]}},"_links":{"self":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/75928","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/comments?post=75928"}],"version-history":[{"count":2,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/75928\/revisions"}],"predecessor-version":[{"id":75987,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/75928\/revisions\/75987"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media\/62187"}],"wp:attachment":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media?parent=75928"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/categories?post=75928"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/tags?post=75928"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}