2

How can I pass an object (Entity) to an OData Action? I can pass simple types and ComplexType, but if try to pass an EntityType I get:

Invalid parameter type 'apitest.Models.Product'. 
A non-binding parameter type must be either Primitive, Complex, 
Collection of Primitive or a Collection of Complex.

Edit:

var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Product>("Products");
modelBuilder.EntitySet<PurchaseOrder>("PurchaseOrders");

var addProduct = modelBuilder.Entity<PurchaseOrder>().Action("AddProduct");
addProduct.Parameter<Product>("product");
addProduct.ReturnsFromEntitySet<PurchaseOrder>("PurchaseOrders");

I've tried replacing addProduct.Parameter<Product>("product"); with:

var productConfig = modelBuilder.StructuralTypes.OfType<EntityTypeConfiguration>().Single(x => x.Name == "Product");
addProduct.SetBindingParameter("product", productConfig, false);

But I haven't been able to find any documentation on how to use SetBindingParameter. If I register Product as a ComplexType, the first code sample works, but then I'm not allowed to register it as Entity.

sker
  • 17,842
  • 8
  • 37
  • 41
  • 1
    Can you post the code for the action in question? Does the Product entity have any custom attributes? – eoghank Nov 01 '13 at 12:48
  • I added some code. There are no attributes on Product. – sker Nov 01 '13 at 18:34
  • What's the signature of your web api controller action? Web api may just expect your object to be first but perhaps you have some other primitive (or non-object) param first? [This article](http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api) details web api parameter binding and may be of use in tracking down the issue. – jandersen Nov 02 '13 at 06:17
  • I've tried all kinds of signature combinations with some or all of these parameters: AddProduct([FromODataUri] int key, Product product, ODataActionParameters parameters). If I'm using the SetBindingParameter defined above I get the following error: "This service doesn't support OData requests in the form '~/entityset/key/unresolved'." I had read that article but there seems to be something else going on since the OData layer handles parameters differently than raw Web Api. – sker Nov 02 '13 at 20:58

2 Answers2

0

You can use Post or Put actions. Just create it in your controller class:

public IHttpActionResult Put([FromODataUri] int key, Product product)
{
    ...
}

I have the same problem in my app and I decided to create DTO classes that are not Entity-types.

Alexander Vasilyev
  • 1,273
  • 2
  • 15
  • 22
0

Assuming that you bind an action to an Entity type this works

builder.EntityType<company>().Action("SetCommunities").CollectionEntityParameter<community>("communities");
public async Task<IHttpActionResult> SetCommunities(Guid key, ODataActionParameters parameters)

To be called in this case by e.g. http://localhost:63358/odata/companies(451735ef-15f2-4a9f-b4b9-d50c6410bf7c)/Default.SetCommunities/

Jaap
  • 81,064
  • 34
  • 182
  • 193
Egbert Nierop
  • 2,066
  • 1
  • 14
  • 16