Thursday, December 13, 2018

odata webapi 2.x on core, function parameters

odata webapi 2.x on core, function parameters

When I needed to add some functions (or actions) to my odata server for my internal database that I want to connect to Dynamics CRM, I found the documentation challenging. Even blogs on this topic did not help much. I had alot of errors.

When setting up a function in your EDM model you can following the instructions. In my domain model, I have a SystemUser and PrincipalPermissions which are a set of permissions needed to determine if you can CRUD an entity or a collection of entities. Nothing special here and I am using the same names as those found in Dynamics CRM for convenience here but just remember, this is my separate database that I need an OData front end for:

var systemUserES = builder.EntitySet<SystemUser>("SystemUsers");
var retrievePrincipalAccessFunc = builder.EntityType<SystemUser>()
	.Function("RetrievePrincipalAccess")
	.ReturnsFromEntitySet<PrincipalPermission>("PrincipalPermissions"); // return single instance
retrievePrincipalAccessFunc.Parameter<string>("type");
retrievePrincipalAccessFunc.Parameter<Guid>("id").Optional();

Here’s the final controller declaration:

[HttpGet]
[ODataRoute("SystemUsers({key})/Encore.RetrievePrincipalAccess(type={otype},id={oid})")]
public  ActionResult<PrincipalPermission> RetrievePrincipalAccess(
	Guid  key,
	string  otype,
	Guid? oid) { ... }

Note the following which I did not find documented:

  • The function parameter names in the EDM spec are for the actual parameters in the function call and not the parameter names in {…} for the actual C# function.
  • The names in the {…} need to match, order does not matter.
  • The GUID in the function call itself (in the HTTP call) should not be quoted even though its a function argument. The type is GUID and GUIDs should not be quoted in the HTTP URL.
  • The parameters in the parameter list do not have [FromODataUri]. If you keep those on the parameters, your route will throw an exception during startup indicating the route is invalid. If you did nothave an ODataRoute then you would want [FromODataUri] on the parameters. The explicit ODataRoute removes the need for FromODataUri.

I worked through this fast enough, but I do find that things like this slow me down a bit.

At least its all working!