Skip to content

OData Connected Service generates code that does not work (in case of EnableQualifiedOperationCall = false) #436

@FrankFK

Description

@FrankFK

Describe the bug

I created a client using OData Connected Service. The client calls a generated OData function. The generated OData function internally uses a route that the server does not accept.

Assemblies affected

OData Connected Service 2022+ Version 1.1.1

Steps to Reproduce

Write a Web API with a bound function as described in Learn OData Actions and functions

Change the code of the action so that it better matches OData:
In BooksController:

    [HttpGet]  // instead of HttpGet("odata/Books/mostRecent()")
    public IActionResult MostRecent()
    {
        var maxBookId = books.Max(x => x.ID);
        return Ok(maxBookId);
    }

In Program.cs:

        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            var modelBuilder = new ODataConventionModelBuilder();
            modelBuilder.EntitySet<Book>("Books");
            modelBuilder.EntityType<Book>().Collection
                  .Function("MostRecent")    // instead of "mostRecent"
                  .Returns<string>();

            builder.Services.AddControllers().AddOData(
                options =>
                {
                    options.Select().Filter().OrderBy()..AddRouteComponents("odata", modelBuilder.GetEdmModel());
                }
                );
            var app = builder.Build();
            app.UseRouting();
            app.UseEndpoints(endpoints => endpoints.MapControllers());
            app.Run();
        }

This example would work without errors. But I have to use an OData service in which RouteOption EnableQualifiedOperationCall has been set to false. This can be reproduced by adding this line to the above example.

                  options.RouteOptions.EnableQualifiedOperationCall = false;

Now I'm going to use OData Connected Service to create a client that uses this API. I use the generated method MostRecent to call the action:

    var mostRecent = container.Books.MostRecent().GetValue();

The generated code internally looks like this:

      _source.CreateFunctionQuerySingle<string>("Default.MostRecent", false);

And it calls this Uri:
http://localhost:5101/odata/Books/Default.MostRecent().
This means that it calls the action with the fully qualified name (i.e., with the namespace “Default” as a prefix). However, because EnableQualifiedOperationCall is set to false, this call does not work. Because of this option, only this call works:
http://localhost:5101/odata/Books/MostRecent()

But I have no way of configuring the OData Connected Services so that this URI is called up.

Expected behaviour

I can configure or use the OData Connected Service so that such actions can be used.

Actual behaviour

I have to manually change the generated code so that the correct URI is called. After each "Update OData Connected Services", I have to do this again.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions