AspNetCoreOData icon indicating copy to clipboard operation
AspNetCoreOData copied to clipboard

CustomUriFunctions do not support nullable parameters

Open Xriuk opened this issue 2 months ago • 0 comments

Assemblies affected Which assemblies and versions are known to be affected e.g. ASP.NET Core OData 8.2.4 (but I feel it affects all the versions)

Describe the bug When adding a custom function for a nullable type when binding that function an exception is thrown:

Expression of type 'System.Int32' cannot be used for parameter of type 'System.Nullable`1[System.Int32]' of method 'System.String MyMethod(System.Nullable`1[System.Int32])' (Parameter 'arg0')
   at System.Dynamic.Utils.ExpressionUtils.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arguments, ParameterInfo pi, String methodParamName, String argumentParamName, Int32 index)
   at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression arg0)
   at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
   at Microsoft.AspNetCore.OData.Query.Expressions.ExpressionBinderHelper.MakeFunctionCall(MemberInfo member, ODataQuerySettings querySettings, Expression[] arguments)
   at Microsoft.AspNetCore.OData.Query.Expressions.QueryBinder.BindCustomMethodExpressionOrNull(SingleValueFunctionCallNode node, QueryBinderContext context)
...

Reproduce steps

public static string MyMethod(int? value){
    ...
}

...

ODataUriFunctions.AddCustomUriFunction("myFunc", new FunctionSignatureWithReturnType(
	EdmCoreModel.Instance.GetString(false),
	EdmCoreModel.Instance.GetInt32(true)
), typeof(...).GetMethod("MyMethod"));

...

// Invoke the func in the query
/...?$compute=myFunc(...) as Result&$select=Result

Expected behavior Custom Uri functions with nullable parameters should work as expected.

Additional context I think that the culprit is here: https://github.com/OData/AspNetCoreOData/blob/3d50b02e67bfff8f8b664ed758f2cbda50152e3e/src/Microsoft.AspNetCore.OData/Query/Expressions/ExpressionBinderHelper.cs#L224-L226 It strips away Nullable parameters regardless because canonical functions don't have overloads for them (but custom ones might have).

Xriuk avatar Oct 16 '25 11:10 Xriuk