-
Notifications
You must be signed in to change notification settings - Fork 0
Controllers
Assume the following simple Product class which we want to query using OData 4.0:
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime ReleaseDate { get; set; }
}
The MicroLite WebApi OData Extension adds support for OData Queries by providing the MicroLiteODataApiController<TEntity, TEntityKey>
.
If you want to enable it, simply derive your controller from the MicroLiteODataApiController<TEntity, TEntityKey>
class:
[RoutePrefix("odata")]
public class ProductODataController : MicroLiteODataApiController<Product, int>
{
}
Note that it is required to use the route prefix 'odata' over 'api' for OData controllers.
This will allow you to call GET http://myservice/odata/Products/$count
which will return the raw integer value of the total number of Products. It is opt-in, add the following method to any controller which you want /$count
for (this is different to the $count=true
in the OData Query Options below).
[HttpGet, Route("Products/$count")]
public Task<IHttpActionResult> Count()
=> this.GetCountResponseAsync();
Example Response:
125
This will allow you to call GET http://myservice/odata/Products(1)
which will return the entity values (or a 404 if no record exists with the requested ID).
[HttpGet, Route("Products({id:int})")]
public Task<IHttpActionResult> Get(int id)
=> this.GetEntityResponseAsync(id);
Example Response:
{ "ProductId": 1, "Name": "Milk", "Price": 1.15, "ReleaseDate": "2012-04-15T00:00:00.0" }
This will allow you to call GET http://myservice/odata/Products(1)/Price
which will return the entity property (or a 404 if no record exists with the requested ID, or a 400 if the property name does not exist).
[HttpGet, Route("Products({id:int})/{propertyName}")]
public Task<IHttpActionResult> GetProperty(int id, string propertyName)
=> this.GetEntityPropertyResponseAsync(id, propertyName);
Example Response:
{ "value": 1.15 }
This will allow you to call GET http://myservice/odata/Products(1)/Price/$value
which will return the property value (or a 404 if no record exists with the requested ID, or a 400 if the property name does not exist).
[HttpGet, Route("Products({id:int})/{propertyName}/$value")]
public Task<HttpResponseMessage> GetPropertyValue(int id, string propertyName) => this.GetEntityPropertyValueResponseAsync(id, propertyName);
Example Response:
1.15
Add the following method to your controller:
[HttpGet, Route("Products")] // The Route should match the entity set name defined in the Entity Data Model
public Task<IHttpActionResult> Get(ODataQueryOptions queryOptions)
=> this.GetEntityResponseAsync(queryOptions);
The following query options are currently supported:
- $select
- $filter
- $skip
- $top
- $orderby
- $count
- $format
$select – this allows you to limit which properties are returned in the query, if no $select value is specified, all properties will be included. Property names must be cased correctly.
URI: /odata/products?$select=ProductId,Name,Price
would return results such as:
[{ "ProductId": 1, "Name": "Milk", "Price": 1.15 }, { "ProductId": 2, "Name": "Bread", "Price": 0.65 } ]
This means that the result set won’t contain properties that you have not specified so you won’t get default values returned in property values which haven’t been retrieved from the database and makes the response payload smaller.
$filter - this allows you to constrain the results returned based upon specified predicates, if no $filter value is specified, all results will be returned (up to the maximum supported by the controller).
Return all products released after 1st Jan 2010:
URI /odata/products?$filter=Released gt 2010-01-01
MicroLite.Extensions.WebApi.OData currently supports the following filter options:
- and
- eq
- ge
- gt
- has (from 7.1.0)
- le
- lt
- ne
- not
- or
- add
- div
- mod
- mul
- sub
-
()
Precedence Grouping
- concat (from 7.1.0)
- contains
- endswith
- indexof
- length
- startswith
- substring
- tolower
- toupper
- trim
- date
- day
- fractionalseconds
- hour
- maxdatetime
- mindatetime
- minute
- month
- now (from 7.1.0)
- second
- totaloffsetminutes
- year
- ceiling
- floor
- round
- cast
- isof
$skip and $top can be used to constrain the number of results returned to implement paging:
URI /odata/products?$skip=50&$top=50
$orderby – this allows you to specify how the results are ordered in the result set.
Sort by Name ascending and then within each Name, ReleaseDate descending:
URI /odata/products?$orderby=Name,ReleaseDate desc
If not specified, the order will default to ascending. If specified, the order must be asc or desc
$count – allows you to ask the results to be returned along with a total count of the results. If not specified, no count will be used.
Include in the results a property called count which contains the total number of results:
URI /odata/products?$count=true
Do not include a count in the results – this is the default behaviour if not specified:
URI /odata/products?$count=false
The query options can be combined to filter results however you like, BUT each option may only appear once.
$format – allows you to override the format the data should be returned in regardless of the value in the content-type HTTP header:
regardless of the content-type header value, return the results in JSON:
URI /odata/products?$format=json
You can validate the types of query which can be executed against a controller by specifying the Validation
They can be specified exclusive of each other and the $top value can be validated by the ValidationSettings
in the controller.
public ProductODataController()
{
// MaxTop will default to 50 if not otherwise specified & will be used to limit the max value
// allowed in $top or constrain the results if no $top is specified in the OData query.
this.ValidationSettings.MaxTop = 100;
}
You can also specify the AllowedFunctions
and AllowedQueryOptions
. By default, all supported functions and query options are allowed.