Web API 2 REST Service Advanced Data Filtering
From the comments above:
You should look into the oData implementation for Web API, there are a couple of MS NuGet packages you have to install. After that its mostly configuring what you want to expose, any restrictions you want to limit the callers to (like max page size), and the rest is done by the client by manipulating the URL to filter, page, sort, etc.
Here an example:
Url sample
This retrieves the top 24 schools in the list sorted by name where the number of students is between 10 and 100 inclusive
/odata/Schools/?$count=true&$top=24&$skip=0&$filter=(numberOfStudents ge 10 and numberOfStudents le 100)&$orderby=name desc
SchoolController.cs
using System.Web.Http;
using System.Web.OData;
using System.Web.OData.Routing;
[ODataRoutePrefix("Schools")]
public sealed class SchoolODataController : ODataController
{
private DbContext _context; // your DbContext implementation, assume some DbSet<School> with the property name Schools
public SchoolODataController(DbContext context)
{
_context = context;
}
[EnableQuery(MaxNodeCount = 200, MaxTop = 100, PageSize = 64 )]
[ODataRoute]
[HttpGet]
public IHttpActionResult Get()
{
return Ok(_context.Schools);
}
}
WebApiConfig.cs
using System.Web.Http;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// other code
config.MapODataServiceRoute("odata", "odata", GetModel());
}
public static IEdmModel GetModel()
{
var builder = new ODataConventionModelBuilder();
builder.EnableLowerCamelCase();
var setOrders = builder.EntitySet<SchoolModel>("Schools").EntityType.HasKey(x => new { x.SchoolId });
return builder.GetEdmModel();
}
}
NuGet packages
Install-Package Microsoft.AspNet.OData
Install-Package Microsoft.OData.Core
Install-Package Microsoft.OData.Edm
Related videos on Youtube
AussieJoe
BY DAY: Conformist to society. BY NIGHT: Non-conformist to society. FOR FUN: Eucalyptus leaves, duh.
Updated on June 04, 2022Comments
-
AussieJoe almost 2 years
My team has currently implemented a REST API (JSON) using the Web API 2 platform for .NET. We have some working URLs, such as:
/api/schools /api/schools/5000 /api/occupations /api/occupations/22
And here is some of our data controller code:
public class OccupationsController : ApiController { // /api/Occupations/1991 public IHttpActionResult GetOccupation(int id) { var occupation = GetAllOccupations().FirstOrDefault((p) => p.OccupationID == id); if (occupation == null) { return NotFound(); } return Ok(occupation); } // /api/occupations public IEnumerable<Occupation> GetAllOccupations() { var ctx = new TCOSDBEntities(); return ctx.Occupations.OrderBy(occupation => occupation.Title); } }
We are now introducing data filtering (based on user checkbox selection) and I am curious how to approach this in our existing API, or if I should abandon REST for filtering down and try a different approach all together?
Here is our checkbox filtering mechanism: Checkbox UI
How can I introduce search parameters in my REST services and DataController methods? Like, how do I get a range filter on a field (like Cost?)? Can I have multiple fields filtering, like Cost, Tuition, etc?
-
Igor about 8 yearsYou should look into the oData implementation for Web API, there are a couple of MS NuGet packages you have to install. After that its mostly configuring what you want to expose, any restrictions you want to limit the callers to (like max page size), and the rest is done by the client by manipulating the URL to filter, page, sort, etc. See this link and this to get started.
-
Igor about 8 yearsBy the way, I'm not advocating you use oData as a blanket approach to everything, just those particular models where you want to expose flexible retrieval by the/a client.
-
AussieJoe about 8 yearsIs it possible with Entity Framework? I noticed the OData example is without EF? I like it though!
-
Igor about 8 yearsAbsolutely. I have been using it for the past 6 months in our projects. Our client's are web browsers so we built a library to create the oData query string (level of abstraction to hide the odata query details). I really could not be happier, it saved us a lot of c# code each time we wanted to expose a model where we wanted flexible searching. Also, with EF, you pass an IQueryable and the database call is executed by the oData framework so its also light weight. The only negative I can think of is its a leaky abstraction in that you are exposing implementation details to the caller.
-
Igor about 8 yearsAnyway, for scenarios like yours above I really do recommend it.
-
AussieJoe about 8 years@Igor Any chance you can provide a sample so I can give you the answer vote? I have implemented it and its really nice :)
-
Igor about 8 yearsHere you go, hope this is of some help for you.
-
-
AussieJoe about 8 yearsvery nice! works like a breeze. I like this solution alot! Cheers!
-
Igor about 8 years@AussieJoe - glad to hear it!
-
AussieJoe about 8 yearsIs it possible to use traditional Web API and OData as well in the configuration? I noticed when I converted my School controller to OData, my other ApiController's no longer work. Can they work together or must all controllers be OData in the API?
-
Igor about 8 years@AussieJoe - Yes, they can be side-by-side in the same project with out any issues. Make sure you add the new route info (like in my example) next to the existing api route info. I have my web api routes prefixed with the default "api/" and the odata routes prefixed with "odata" (like in the example).
-
SUN over 6 years@Igor can you post complete implementation of this including dbContext? I am beginner to web api so need to understand .