OData / WebApi

OData Web API: A server library built upon ODataLib and WebApi
https://docs.microsoft.com/odata
Other
854 stars 476 forks source link

Unlike with MVC5 OData, extra, unused and not mapped parameter on the API endpoints DTO raises an exception even if not used in the query... #1245

Open hidegh opened 6 years ago

hidegh commented 6 years ago

NotSupportedException: The specified type member 'Reserved' is not supported in LINQ to Entities.

Assemblies affected

microsoft.aspnetcore.odata\7.0.0-beta1

Reproduce steps

Startup.cs (camel case and enable case insensitive does not work - BUG)

        services.TryAddSingleton(_ =>
        {
            var mb = new ODataConventionModelBuilder(_, true);
            mb.EnableLowerCamelCase();
            return mb;
        });

        services.TryAddSingleton(_ => new ODataUriResolver() { EnableCaseInsensitive = true });

        services.AddOData();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");

            routes.MapRoute(
                name: "apiDefault",
                template: "api/{controller=Home}/{action=Index}/{id?}");

            routes.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
            routes.EnableDependencyInjection();
        });

Controller:

    public IQueryable<SalesOrderDTO> GetSalesOrders()
    {
        return 
            from o in DbContext.Orders
            select new SalesOrderDTO()
            {
                OrderId = o.OrderId,
                OrderNumber = o.OrderNumber
            };

        return q;
    }

    public class SalesOrderDTO
    {
        public int OrderId {get;set;}
        public string OrderNumber {get;set;}
        public string Reserved { get;set; }
    }

Expected result

Since the extra fields are not used in the queries and are not present on the IQueryable, it should pass. The MVC5 OData was ignorant of extra params.

Actual result

The exception (see above).

Additional detail

no

robward-ms commented 6 years ago

@hidegh - Can you provide an example URL? I suspect one issue is that you are using OData components outside of an OData route, i.e. there is no MapODataServiceRoute() and the URL's root path is api or null.

hidegh commented 6 years ago

@robward-ms yes, I do use the classic API endpoint (ohh, not in the sample), so:

[EnableQuery] [Route("api/orders")] public IQueryable GetSalesOrders()

and so the call is like: localhost:10900/api/orders/?$top=5&$filter=contains(OrderNumber,'123')

Since OData is great for querying, and there are some components already using OData as source, the aim is to allow odata queries against our endpoints (which might be IQueryable over in-memory objects) with minimal config.

Actually nor camel-case name formatting, nor case insensitive property names are allowed and also haven't tried case-insensitive searches, but the concept above worked nicely before.

robward-ms commented 6 years ago

@hidegh - To just to clarify, the scenario you want to enable is using EnableQueryAttribute outside of the context of an OData route and it's formatters, routing convents, etc...

hidegh commented 6 years ago

@robward-ms exactly. since it's the most obvious use-case for OData - querying. it also works with some limitations which the prev. versions did not had (see 1st entry here).

Actually what I don't get is, that there's the base OData library & now there's a lot of extra work with the extras on AspNetCore. But taking the simplicity approach (at least the query part), it's just a query in the URI, which could be treated as a string (of key/values, so not really WEB dependent) and the rest is just to apply parsed value on an IQueryable. Maybe supporting this basics (queries only) in a separate AspNetCore library would make a sense - especially with case insensitive/camelCase property invariance. Ever considered this?

hidegh commented 4 years ago

@robward-ms hi, yes, I use default API routes, similar to this: https://github.com/OData/WebApi/issues/1748#issuecomment-565027024.

I was although not able to reproduce the issue with the latest .NET Core 3.1 and Odata 7.2.3 version (I use a fairly simple app, and just added the extra, non projected parameter to the Dto which then I even used in querying)...