How to implement OData $expand and $select in Web API
Create a new Web API project in visual studio and add below nuget packages to enable odata
"Microsoft.AspNet.OData"
Step 2:
Create below model class Product, Supplier, Category and ProductList
-----------------------------------------------------------------------------
using System.ComponentModel.DataAnnotations.Schema;
namespace ODataExpandAndSelect.Models
{
public class Product
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
[ForeignKey("Supplier")]
public string SupplierId { get; set; }
public virtual Supplier Supplier { get; set; }
}
}
----------------------------------------------------------------------------------------
using System.ComponentModel.DataAnnotations;
namespace ODataExpandAndSelect.Models
{
public class Supplier
{
[Key]
public string Key { get; set; }
public string Name { get; set; }
}
}
----------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
namespace ODataExpandAndSelect.Models
{
public class Category
{
public Category()
{
Products = new HashSet();
}
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection Products { get; set; }
}
------------------------------------------------------------------------------------------
public class ProductList
{
public IQueryable getProducts()
{
List products = new List();
Category c1 = new Category() { ID = 1, Name = "Category1", Products = products };
Category c2 = new Category() { ID = 2, Name = "Category2", Products = products };
Supplier s1 = new Supplier() { Key = "s1", Name = "Supplier1" };
Supplier s2 = new Supplier() { Key = "s2", Name = "Supplier2" };
Product p1 = new Product() { ID = 1, Category = c1, CategoryId = 1, Name = "product1", Price = 100.50M , Supplier = s1, SupplierId = "SupplierS1" };
Product p2 = new Product() { ID = 2, Category = c2, CategoryId = 2, Name = "product2", Price = 200.50M , Supplier = s2, SupplierId = "SupplierS2" };
products.Add(p1);
products.Add(p2);
return products.AsQueryable();
}
}
}
------------------------------------------------------------------------------------
Since I am not using any database in this example, So I have created ProductList class and returning some dummy data, You may use any database or entity framework as per your requirement.
Step 3:
In WebApi.Config Please add below changes
using System.Linq;
using System.Web.Http;
using Microsoft.AspNet.OData.Batch;
using Microsoft.AspNet.OData.Builder;
using Microsoft.AspNet.OData.Extensions;
using Microsoft.OData.Edm;
using ODataExpandAndSelect.Models;
namespace ODataExpandAndSelect
{
public static class WebApiConfig
{
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.Namespace = "WebAPITest";
builder.ContainerName = "DefaultContainer";
builder.EntitySet("Product");
builder.EntitySet("Category");
builder.EntitySet("Supplier");
var edmModel = builder.GetEdmModel();
return edmModel;
}
public static void Register(HttpConfiguration config)
{
config.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
config.MapODataServiceRoute("odata", null, GetEdmModel(), new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
config.EnsureInitialized();
}
}
}
You can expand to next level through comma separated like below query
You can download the full code from my GitHub repository
And follow my YouTube channel for detailed description
Step 1:Create a new Web API project in visual studio and add below nuget packages to enable odata
"Microsoft.AspNet.OData"
Step 2:
Create below model class Product, Supplier, Category and ProductList
-----------------------------------------------------------------------------
using System.ComponentModel.DataAnnotations.Schema;
namespace ODataExpandAndSelect.Models
{
public class Product
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
[ForeignKey("Supplier")]
public string SupplierId { get; set; }
public virtual Supplier Supplier { get; set; }
}
}
----------------------------------------------------------------------------------------
using System.ComponentModel.DataAnnotations;
namespace ODataExpandAndSelect.Models
{
public class Supplier
{
[Key]
public string Key { get; set; }
public string Name { get; set; }
}
}
----------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
namespace ODataExpandAndSelect.Models
{
public class Category
{
public Category()
{
Products = new HashSet
}
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection
}
------------------------------------------------------------------------------------------
public class ProductList
{
public IQueryable
{
List
Category c1 = new Category() { ID = 1, Name = "Category1", Products = products };
Category c2 = new Category() { ID = 2, Name = "Category2", Products = products };
Supplier s1 = new Supplier() { Key = "s1", Name = "Supplier1" };
Supplier s2 = new Supplier() { Key = "s2", Name = "Supplier2" };
Product p1 = new Product() { ID = 1, Category = c1, CategoryId = 1, Name = "product1", Price = 100.50M , Supplier = s1, SupplierId = "SupplierS1" };
Product p2 = new Product() { ID = 2, Category = c2, CategoryId = 2, Name = "product2", Price = 200.50M , Supplier = s2, SupplierId = "SupplierS2" };
products.Add(p1);
products.Add(p2);
return products.AsQueryable();
}
}
}
------------------------------------------------------------------------------------
Since I am not using any database in this example, So I have created ProductList class and returning some dummy data, You may use any database or entity framework as per your requirement.
Step 3:
In WebApi.Config Please add below changes
using System.Linq;
using System.Web.Http;
using Microsoft.AspNet.OData.Batch;
using Microsoft.AspNet.OData.Builder;
using Microsoft.AspNet.OData.Extensions;
using Microsoft.OData.Edm;
using ODataExpandAndSelect.Models;
namespace ODataExpandAndSelect
{
public static class WebApiConfig
{
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.Namespace = "WebAPITest";
builder.ContainerName = "DefaultContainer";
builder.EntitySet
builder.EntitySet
builder.EntitySet
var edmModel = builder.GetEdmModel();
return edmModel;
}
public static void Register(HttpConfiguration config)
{
config.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
config.MapODataServiceRoute("odata", null, GetEdmModel(), new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
config.EnsureInitialized();
}
}
}
Step 4:
Create a ProductController in controller folder like below
using System.Linq;
using Microsoft.AspNet.OData;
using ODataExpandAndSelect.Models;
namespace ODataExpandAndSelect.Controllers
{
public class ProductController : ODataController
{
[EnableQuery]
public IQueryable Get()
{
ProductList list = new ProductList();
var data = list.getProducts();
return data;
}
}
}
Step 5:
In Global.asax.cs add below changes
using System.Web.Http;
namespace ODataExpandAndSelect
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
}
Step 6:
Run your application on IIS express and use query like below
http://localhost:5197/Product?$expand=Category
You can expand to next level through comma separated like below query
http://localhost:5197/Product?$expand=Category,Supplier
For $select you can you below query
http://localhost:5197/Product?$select=Price
Thank you
Happy coding
No comments:
Post a Comment