4.6 Function parameter support
Since Web API OData V5.5-beta, it supports the following types as function parameter:
- Primitive
- Enum
- Complex
- Entity
- Entity Reference
- Collection of above
Let’s see how to build and use the above types in function.
CLR Model
First of all, we create the following CLR classes as our model:
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
public class SubCustomer : Customer
{
public double Price { get; set; }
}
public class Address
{
public string City { get; set; }
}
public class SubAddress : Address
{
public string Street { get; set; }
}
public enum Color
{
Red,
Blue,
Green
}
Build Edm Model
Now, we can build the Edm Model as:
private static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.EntitySet<Customer>("Customers");
builder.ComplexType<Address>();
builder.EnumType<Color>();
BuildFunction(builder);
return builder.GetEdmModel();
}
where, BuildFunction() is a helper function in which functions can be built.
Primitive and Collection of Primitive parameter
Configuration
In BuildFunction(), we can configure a function with Primitive
and collection of Primitive
parameters:
var function = builder.EntityType<Customer>().Collection.Function("PrimtiveFunction").Returns<string>();
function.Parameter<int>("p1");
function.Parameter<int?>("p2");
function.CollectionParameter<int>("p3");
Routing
In the CustomersController
, add the following method:
[HttpGet]
public string PrimtiveFunction(int p1, int? p2, [FromODataUri]IEnumerable<int> p3)
{
...
}
Request Samples
We can invoke the function as:
~/odata/Customers/Default.PrimitiveFunction(p1=1,p2=9,p3=[1,3,5,7,9])
~/odata/Customers/Default.PrimitiveFunction(p1=2,p2=null,p3=[1,3,5,7,9])
~/odata/Customers/Default.PrimitiveFunction(p1=3,p2=null,p3=@p)?@p=[2,4,6,8]
Enum and Collection of Enum parameter
Configuration
In BuildFunction(), we can configure a function with Enum
and collection of Enum
parameters:
var function = builder.EntityType<Customer>().Collection.Function("EnumFunction").Returns<string>();
function.Parameter<Color>("e1");
function.Parameter<Color?>("e2"); // nullable
function.CollectionParameter<Color?>("e3"); // Collection of nullable
Routing
In the CustomersController
, add the following method :
[HttpGet]
public string EnumFunction(Color e1, Color? e2, [FromODataUri]IEnumerable<Color?> e3)
{
...
}
Request Samples
We can invoke the Enum function as:
~/odata/Customers/Default.EnumFunction(e1=NS.Color'Red',e2=NS.Color'Green',e3=['Red', null, 'Blue'])
~/odata/Customers/Default.EnumFunction(e1=NS.Color'Blue',e2=null,e3=['Red', null, 'Blue'])
~/odata/Customers/Default.EnumFunction(e1=NS.Color'Blue',e2=null,e3=@p)?@p=['Red', null, 'Blue']
Complex and Collection of Complex parameter
Configuration
In BuildFunction(), we can configure a function with Complex
and collection of Complex
parameters:
var function = builder.EntityType<Customer>().Collection.Function("ComplexFunction").Returns<string>();
function.Parameter<Address>("c1");
function.CollectionParameter<Address>("c2");
Routing
In the CustomersController
, add the following method :
[HttpGet]
public string ComplexFunction([FromODataUri]Address c1, [FromODataUri]IEnumerable<Address> c2)
{
...
}
Request Samples
We can invoke the complex function as:
~/odata/Customers/Default.ComplexFunction(c1=@x,c2=@y)?@x={\"@odata.type\":\"%23NS.Address\",\"City\":\"Redmond\"}&@y=[{\"@odata.type\":\"%23NS.Address\",\"City\":\"Redmond\"},{\"@odata.type\":\"%23NS.SubAddress\",\"City\":\"Shanghai\", \"Street\":\"Zi Xing Rd\"}]
~/odata/Customers/Default.ComplexFunction(c1={\"@odata.type\":\"%23NS.Address\",\"City\":\"Redmond\"},c2=[{\"@odata.type\":\"%23NS.Address\",\"City\":\"Redmond\"},{\"@odata.type\":\"%23NS.SubAddress\",\"City\":\"Shanghai\", \"Street\":\"Zi Xing Rd\"}])
~/odata/Customers/Default.ComplexFunction(c1=null,c2=@p)?@p=[null,{\"@odata.type\":\"%23NS.SubAddress\",\"City\":\"Shanghai\", \"Street\":\"Zi Xing Rd\"}]
Entity and Collection of Entity parameter
Configuration
In BuildFunction(), we can configure a function with Entity
and collection of Entity
parameters:
var function = builder.EntityType<Customer>().Collection.Function("EntityFunction").Returns<string>();
function.EntityParameter<Customer>("a1");
function.CollectionEntityParameter<Customer>("a2");
It’s better to call EntityParameter<T>
and CollectionEntityParameter<T>
to define entity and collection of entity parameter.
Routing
In the CustomersController
, add the following method :
[HttpGet]
public string EntityFunction([FromODataUri]Customer a1, [FromODataUri]IEnumerable<Customer> a2)
{
...
}
Request Samples
We can invoke the entity function as:
~/odata/Customers/Default.EntityFunction(a1=@x,a2=@y)?@x={\"@odata.type\":\"%23NS.Customer\",\"Id\":1,\"Name\":\"John\"}&@y={\"value\":[{\"@odata.type\":\"%23NS.Customer\",\"Id\":2, \"Name\":\"Mike\"},{\"@odata.type\":\"%23NS.SubCustomer\",\"Id\":3,\"Name\":\"Tony\", \"Price\":9.9}]}
~/odata/Customers/Default.EntityFunction(a1=@x,a2=@y)?@x=null&@y={\"value\":[]}
However, only parameter alias is supported for entity.
Entity Reference and collection of Entity Reference parameter
In fact, we can’t build a function with entity reference as parameter. However, we can call the function with entity parameter using entity reference value. So, without any change for the EntityFunction
, we can call as:
~/odata/Customers/Default.EntityFunction(a1=@x,a2=@y)?@x={\"@odata.id\":\"http://localhost/odata/Customers(2)\"}&@y={\"value\":[{\"@odata.id\":\"http://localhost/odata/Customers(2)\"},{\"@odata.id\":\"http://localhost/odata/Customers(3)\"}]}
FromODataUri
‘[FromODataUri]’ is mandatory for complex, entity and all collection. However, it is optional for Primitive & Enum. But for string primitive type, the value will contain single quotes without ‘[FromODataUri]’.
Thanks.
For un-typed scenario, please refer to untyped page.