title: WebAPI OData Actions Sample - Differentianting between CheckOut and CheckOutMany actions
body: <p>I've been busy doing my own customisations to a T4 template so that I can have strongly typed OData action invocation from a .NET client.  It will probably be my first open source thing that I create :)</p>
  
  <p>Anyway, I've testing and developing against the WebAPI OData sample for OData actions called "ODataActionsSample".  For those who want to play along at home you can find the samples at <a href="http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/ODataActionsSample/" rel="nofollow">http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/ODataActionsSample/</a>.  </p>
  
  <p>The sample has several more interesting actions.  At the moment I'm trying to support the two collection-based actions since I have the others under control already. These two actions are the <code>CheckOut</code> action (the override which accepts $filter queries) and the <code>CheckOutMany</code> action (which accepts a collection of movie IDs).</p>
  
  <p>Code from the sample...</p>
  
  <pre><code>        // CheckOut action
          // URI: ~/odata/Movies/CheckOut
          // Shows how to bind to a collection, instead of a single entity.
          // This action also accepts $filter queries. For example:
          //     ~/odata/Movies/CheckOut?$filter=Year eq 2005
          var checkOutFromCollection = modelBuilder.Entity&lt;Movie&gt;().Collection.Action("CheckOut");
          checkOutFromCollection.ReturnsCollectionFromEntitySet&lt;Movie&gt;("Movies");
  
          // CheckOutMany action
          // URI: ~/odata/Movies/CheckOutMany
          // Shows an action that takes a collection parameter.
          ActionConfiguration checkoutMany = modelBuilder.Entity&lt;Movie&gt;().Collection.Action("CheckOutMany");
          checkoutMany.CollectionParameter&lt;int&gt;("MovieIDs");
          checkoutMany.ReturnsCollectionFromEntitySet&lt;Movie&gt;("Movies");
  </code></pre>
  
  <p>The metadata generated for these is nearly identical.  It is</p>
  
  <pre><code>    &lt;FunctionImport Name="CheckOut" ReturnType="Collection(ODataActionsSample.Models.Movie)" IsBindable="true" EntitySet="Movies" m:IsAlwaysBindable="true"&gt;
        &lt;Parameter Name="bindingParameter" Type="Collection(ODataActionsSample.Models.Movie)" Nullable="false" /&gt;
      &lt;/FunctionImport&gt;
      &lt;FunctionImport Name="CheckOutMany" ReturnType="Collection(ODataActionsSample.Models.Movie)" IsBindable="true" EntitySet="Movies" m:IsAlwaysBindable="true"&gt;
        &lt;Parameter Name="bindingParameter" Type="Collection(ODataActionsSample.Models.Movie)" Nullable="false" /&gt;
        &lt;Parameter Name="MovieIDs" Type="Collection(Edm.Int32)" Nullable="false" /&gt;
      &lt;/FunctionImport&gt;
  </code></pre>
  
  <p>As you can see in the comments from the sample, the URI to invoke each is quite different but there's not really any clues in the metadata which says that the <code>CheckOut</code> action accepts what's basically an IQueryable versus the <code>CheckOutMany</code> action which accepts a set of MovieIDs.  Yes I see that the <code>CheckOutMany</code> action has the extra parameter, but it shouldn't really have a BindingParameter entry in my opinion.</p>
  
  <p>I'm thinking I could just have a heuristic to pick up this very case - where we accept a BindingParameter that's a collection but then also accept a collection that consists of primitives matching the entity of interest's single key type (in this case that's <code>int</code>).  Frankly that's a bit wobbly but it would at least work.</p>
  
  <p>Direct questions (but comments on the above is very much appreciated!)</p>
  
  <p>a) Is this the only way to go (ie, make a heuristic)?</p>
  
  <p>b) Could we change the 'ActionConfiguration' setup such that the <code>CheckOutMany</code> doesn't bind to the collection the same was as <code>CheckOut</code> does?</p>
  
  <p>c) Alternatively is this a design flaw, bug or just functionality that's not quite baked yet?</p>