title: How to pass Array to OData function in ASP.NET Web API implementation?
body: <p>The specification of OData V4 states that it MUST be possible:
  <a href="https://issues.oasis-open.org/browse/ODATA-636" rel="noreferrer">https://issues.oasis-open.org/browse/ODATA-636</a>.</p>
  
  <blockquote>
    <p>"Complex types and arrays can only be passed to functions through
    parameter aliases"</p>
  </blockquote>
  
  <p>When I'm trying to pass an array with OData parameter aliases an exception occurs.</p>
  
  <blockquote>
    <p>/TestEntities/NS.TestFunction(ArrayHere=@p)?@p=[1,2,3]</p>
  </blockquote>
  
  <p>Results in:</p>
  
  <blockquote>
    <p>Unable to cast object of type 'EdmValidCoreModelPrimitiveType' to type
    'Microsoft.OData.Edm.IEdmStructuredType</p>
  </blockquote>
  
  <p>The interesting thing is that the metadata document is correctly composed for such cases:</p>
  
  <pre><code>&lt;Function Name="TestFunction" IsBound="true"&gt;
    &lt;Parameter Name="bindingParameter" Type="Collection(NS.TestEntity)"/&gt;
    &lt;Parameter Name="ArrayHere" Type="System.Int32[]"/&gt;
    &lt;ReturnType Type="Collection(NS.TestEntity)"/&gt;
  &lt;/Function&gt;
  </code></pre>
  
  <p>Is it possible with ASP.NET MVC Web API 2 OData to pass an array to OData function in query string?</p>
  
  <p><strong>UPDATE:</strong> </p>
  
  <p>Here is the code to build the EDM model and the controller.</p>
  
  <pre><code> var builder = new ODataConventionModelBuilder();
  
   builder.Namespace = "NS";
  
   builder.EntitySet&lt;TestEntity&gt;("TestEntities");
  
   builder.EntityType&lt;TestEntity&gt;().Collection
      .Function("TestFunction")
      .ReturnsCollectionFromEntitySet&lt;TestEntity&gt;("TestEntities")
      .Parameter&lt;int[]&gt;("ArrayHere");
  </code></pre>
  
  <p>Controller:</p>
  
  <pre><code>public class TestEntitiesController : ODataController
  {
      public IEnumerable&lt;TestEntity&gt; TestFunction(int[] arrayHere)
      {
          throw new NotImplementedException();
      }
  }
  </code></pre>
  
  <p>Marking parameter with <code>[FromODataUri]</code> does not solve the problem.</p>
  
  <p><strong>UPDATE 2:</strong></p>
  
  <p>Here is the stack trace:</p>
  
  <pre><code>at Microsoft.OData.Core.UriParser.TypePromotionUtils.CanConvertTo(SingleValueNode sourceNodeOrNull, IEdmTypeReference sourceReference, IEdmTypeReference targetReference)
  at Microsoft.OData.Core.UriParser.Parsers.MetadataBindingUtils.ConvertToTypeIfNeeded(SingleValueNode source, IEdmTypeReference targetTypeReference)
  at Microsoft.OData.Core.UriParser.Parsers.FunctionCallBinder.BindSegmentParameters(ODataUriParserConfiguration configuration, IEdmOperation functionOrOpertion, ICollection`1 segmentParameterTokens)
  at Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.TryBindingParametersAndMatchingOperation(String identifier, String parenthesisExpression, IEdmType bindingType, ODataUriParserConfiguration configuration, ICollection`1&amp; boundParameters, IEdmOperation&amp; matchingOperation)
  at Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.TryCreateSegmentForOperation(ODataPathSegment previousSegment, String identifier, String parenthesisExpression)
  at Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.CreateNextSegment(String text)
  at Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.ParsePath(ICollection`1 segments)
  at Microsoft.OData.Core.UriParser.Parsers.ODataPathFactory.BindPath(ICollection`1 segments, ODataUriParserConfiguration configuration)
  at Microsoft.OData.Core.UriParser.ODataUriParser.ParsePathImplementation()
  at Microsoft.OData.Core.UriParser.ODataUriParser.Initialize()
  at System.Web.OData.Routing.DefaultODataPathHandler.Parse(IEdmModel model, String serviceRoot, String odataPath, Boolean enableUriTemplateParsing)
  at System.Web.OData.Routing.DefaultODataPathHandler.Parse(IEdmModel model, String serviceRoot, String odataPath)
  at System.Web.OData.Routing.ODataPathRouteConstraint.Match(HttpRequestMessage request, IHttpRoute route, String parameterName, IDictionary`2 values, HttpRouteDirection routeDirection)
  at System.Web.Http.Routing.HttpRoute.ProcessConstraint(HttpRequestMessage request, Object constraint, String parameterName, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)
  at System.Web.Http.Routing.HttpRoute.ProcessConstraints(HttpRequestMessage request, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)
  at System.Web.Http.Routing.HttpRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request)
  at System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext)
  </code></pre>