When parsing an OData URI with unbound actions and parameters, the following exception is thrown:
The request URI is not valid. The segment 'TestAction' cannot include key predicates, however it may end with empty parenthesis
. The code below reproduces the exception:
var builder = new ODataConventionModelBuilder
{
Namespace = "Test",
ContainerName = "Test"
};
var action = builder.Action("TestAction").Returns<long>();
action.Parameter<int?>("x");
action.Parameter<int?>("y");
var model = builder.GetEdmModel();
var parser = new ODataUriParser(model, new Uri("TestAction(x=1,y=2)", UriKind.Relative));
var path = parser.ParsePath();
I've investigated the Microsoft.OData.Core
source codes and found this in the FunctionOverloadResolver
class:
try
{
if (parameterNames.Count > 0)
{
// In this case we have to return a function so filter out actions because the number of parameters > 0.
candidateMatchingOperationImports = resolver.ResolveOperationImports(model, identifier).RemoveActionImports(out foundActionImportsWhenLookingForFunctions).FilterFunctionsByParameterNames(parameterNames, resolver.EnableCaseInsensitive).Cast<IEdmOperationImport>().ToList();
}
else
{
candidateMatchingOperationImports = resolver.ResolveOperationImports(model, identifier).ToList();
}
}
catch (Exception exc)
{
if (!ExceptionUtils.IsCatchableExceptionType(exc))
{
throw;
}
throw new ODataException(ODataErrorStrings.FunctionOverloadResolver_FoundInvalidOperationImport(identifier), exc);
}
if (foundActionImportsWhenLookingForFunctions.Count > 0)
{
throw ExceptionUtil.CreateBadRequestError(ODataErrorStrings.RequestUriProcessor_SegmentDoesNotSupportKeyPredicates(identifier));
}
Why the resolver class needs to filter out the actions when the operation has parameters?
I've finally figured out the problem. The action parameters should be on the request payload. So the URI should look like:
var parser = new ODataUriParser(model, new Uri("TestAction", UriKind.Relative));