Open flibustier7seas opened 6 years ago
@flibustier7seas Optional parameter means the parameter maybe has default value. But for the function syntax, all parameters (include optional parameters) should be presented in the route template.
In your scenario, you should remove the first one and keep/change the second one as:
[ODataRoute("Users/GetFirstName(firstName={firstName})")]
public string GetFirstName([FromODataUri]string firstName = "Unknown")
{
return firstName;
}
Hope it can help. Thanks.
@xuzhg
But for the function syntax, all parameters (include optional parameters) should be presented in the route template.
I can skip optional parameters in the route template for function with 2 parameters:
Request: http://localhost:63000/v1/Users/GetFullName(firstName='Foo')
var getFullName = builder.EntityType<User>().Collection
.Function("GetFullName")
.Returns<string>();
getFullName.Parameter<string>("firstName").Required();
getFullName.Parameter<string>("lastName").Optional().HasDefaultValue("Unknown");
[ODataRoute("Users/GetFullName(firstName={firstName})")]
public string GetFullName(string firstName)
{
return GetFullName(firstName, "Unknown");
}
Why cannot skip optional parameter in the route template for function with single optional parameter?
@flibustier7seas In my understanding, "optional" means its value can be optional, but not for the syntax. for a function or action, its syntax is function name plus the parameter type. That's different with the "method" in C#. I would like @mikepizzo can share his thoughts about the "optional"
@xuzhg In my understanding, when a parameter is marked as "optional", it can be omitted when the function is called, as in "C#"
https://www.odata.org/blog/OData-401-Committee-Spec-Published/
Optional Function Parameters – Function parameters can be annotated as optional. Optional parameters may be omitted when invoking the function.
@raheph @xuzhg @mikepizzo any updates on this issue?
Any updates? Following.
@denious It should be fixed in the ODL. Would you please try the latest version and share us your finding. Thanks
Running Microsoft.AspNetCore.OData 7.1.0 I confirm the same buggy behavior as originally described:
Expected 200 in these scenarios:
Only scenario that works is the last one, the first two return 404:
Method signature:
[ODataRoute("GetSearchFilterOperators(filter={filter})")]
[HttpGet]
[Produces("application/json")]
[ProducesResponseType(typeof(ODataValue<IEnumerable<SearchFilterOperator>>), (int)HttpStatusCode.OK)]
public IQueryable<SearchFilterOperator> GetSearchFilterOperators([FromODataUri] string filter = null)
ODATA config for the function:
var getSearchFilerOperatorFunc = entityType.Collection
.Function("GetSearchFilterOperators")
.ReturnsCollection<SearchFilterOperator>();
var filterParam = getSearchFilerOperatorFunc.Parameter<string>("filter");
filterParam.Optional();
filterParam.HasDefaultValue(null);
@xuzhg Facing the same issue with Microsoft.AspNetCore.OData 7.5.6 and .Net core 3.1. Do we have any available resolution for this?
Same for me, with .NET 5.0 Surprinsingly, it was working on ASP.NET MVC and .NET Framework
Running into this problem myself, I discovered you could overload the odata function configurations by adding the same-named function multiple times with different parameters:
builder.EntityType<ClientViewModel>()
.Function("TaskActivityStatistics")
.ReturnsFromEntitySet<TaskActivityStatistics>("TaskActivityStatistics");
var getClientTaskActivityStatistics = builder.EntityType<ClientViewModel>()
.Function("TaskActivityStatistics")
.ReturnsFromEntitySet<TaskActivityStatistics>("TaskActivityStatistics")
.Parameter<string>("filter");
Which allowed me to create a single method on the controller that works for both. In my example: TaskActivityStatistics([FromODataUri] int key, string? filter = null)
Looking at the /$odata
debug endpoint, both odata functions are registered properly and work as expected (still have to use the parenthesis, unfortunately):
{
"DisplayName": "ClientsController.TaskActivityStatistics (WebApi)",
"HttpMethods": [
"GET"
],
"Pattern": "odata/workspace/Clients({key})/TaskActivityStatistics()",
"IsODataRoute": true
},
{
"DisplayName": "ClientsController.TaskActivityStatistics (WebApi)",
"HttpMethods": [
"GET"
],
"Pattern": "odata/workspace/Clients({key})/TaskActivityStatistics(filter={filter})",
"IsODataRoute": true
},
When defining a function with single optional parameter, api returns 500 (Internal Server Error).
Assemblies affected
Microsoft.AspNet.OData 7.0.1
Reproduce steps
Request
http://localhost:63000/v1/Users/GetFirstName()
Expected result
Actual result
Status:
500 Internal Server Error
Additional detail
Example: https://github.com/flibustier7seas/odata-example/tree/optional-parameter#optional-parameter-not-working-for-function-with-single-argument