simple-odata-client / Simple.OData.Client

MIT License
329 stars 191 forks source link

Call odata function or action with paramater finish with HTTP 404 Not Found #583

Open v0111d opened 5 years ago

v0111d commented 5 years ago

I have problem call function or action with parameters.

Server side is ASP.NET Core 2.2 OData 4 API.

Schema:

<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Default">
<Function Name="Men" IsBound="true">
<Parameter Name="bindingParameter" Type="Collection(Wdm.Core.Models.User)"/>
<ReturnType Type="Wdm.Core.Models.User"/>
</Function>
<Function Name="NewUsers" IsBound="true">
<Parameter Name="bindingParameter" Type="Collection(Wdm.Core.Models.User)"/>
<Parameter Name="Since" Type="Edm.DateTimeOffset" Nullable="false"/>
<ReturnType Type="Wdm.Core.Models.User"/>
</Function>
<Action Name="Status" IsBound="true">
<Parameter Name="bindingParameter" Type="Wdm.Core.Models.User"/>
<Parameter Name="status" Type="Edm.String"/>
</Action>
<EntityContainer Name="Container">
<EntitySet Name="Users" EntityType="Wdm.Core.Models.User"/>
<EntitySet Name="User" EntityType="Wdm.Core.Models.User"/>
</EntityContainer>
</Schema>

Function

        [HttpGet]
        [Produces("application/json")]
        [ProducesResponseType(typeof(IEnumerable<User>), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public async Task<ActionResult<IEnumerable<User>>> NewUsers(DateTime since)
        {}

When I try call this function from SwaggerUI function is available on uri

https://localhost:8089/odata/v3/Users/NewUsers(Since=2019-03-05)?%24count=false

curl -X GET "https://localhost:8089/odata/v3/Users/NewUsers(Since=2019-03-05)?%24count=false" -H "accept: application/json"

Simple.odata.client call function on uri https://localhost:8089/odata/v3/Users/Default.NewUsers(since=2019-03-05T18%3A48%3A06.8161531%2B01%3A00)

           var men = await client.For<User>()
                                  .Function("NewUsers")
                                  .Set(new { since = DateTime.Now })
                                  .ExecuteAsEnumerableAsync();

Response is HTTP 404.

Similar issue for action.

Action

        [HttpPost]
        [ODataRoute("({key})/Status")]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public async Task<ActionResult> Status(int key, ODataActionParameters parameters){}

When I try call this function from SwaggerUI function is available on uri

https://localhost:44307/odata/v3/Users(1)/Status

curl -X POST "https://localhost:44307/odata/v3/Users(1)/Status" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"status\": \"string\"}"

Simple.odata.client call function on uri https://localhost:8089/odata/v3/Users/Default.Status

Payload

{"status":"new status"}

            await client.For<User>()
                        .Action("Status")
                        .Set(new {status = "new status"})
                        .ExecuteAsync();

Response is HTTP 404.

vidarkongsli commented 5 years ago

I have come across a similar problem. The solution I found was to add a namespace to the schema: <Schema Namespace="MyNamespace">. The client library will automatically read this from the metadata. The actual URL for the action will be MyNamespace.Status.

v0111d commented 5 years ago

@vidarkongsli : thank you