. Net Core. OData $ expand maxdeep не работает с результатом сериализации - PullRequest
0 голосов
/ 18 марта 2020

Я начинаю с проекта OData WEB APi. Я использую. Net Core 3.1 и OData 7.3.0.

Мой запуск такой:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddOData();
            services.AddODataQueryFilter();

            services.AddDbContext<Context>(options => options.UseSqlServer("Server=localhost;Database=DB;Trusted_Connection=True;"));

            services.AddMvc(options =>
            {
                options.EnableEndpointRouting = false;

                //options.OutputFormatters.Insert(0, new Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonOutputFormatter(
                //    new Newtonsoft.Json.JsonSerializerSettings()
                //    {
                //        MaxDepth = 10,
                //        NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
                //        Formatting = Newtonsoft.Json.Formatting.Indented
                //    },
                //    System.Buffers.ArrayPool<char>.Create(), options));

            }).AddNewtonsoftJson(o => {
                o.SerializerSettings.MaxDepth = 10;
                o.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

            services.AddControllers();
        }
      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }


            app.UseHttpsRedirection();

            app.UseMvc(routeBuilder =>
            {
                routeBuilder.EnableDependencyInjection();

                routeBuilder.Select().Filter().OrderBy().Expand().Count().MaxTop(10);

                routeBuilder.MapODataServiceRoute("odata", "odata", GetEdmModel(app.ApplicationServices));

            });

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

        private static IEdmModel GetEdmModel(IServiceProvider serviceProvider)
        {
            ODataModelBuilder builder = new ODataConventionModelBuilder(serviceProvider);

            builder.EntitySet<Valores>("Valores")
                    .EntityType
                    .Filter()
                    .Count()
                    .Expand(5)
                    .OrderBy()
                    .Page()
                    .Select();

            return builder.GetEdmModel();
        }
    }

Контроллер:

[ODataRoute]
        [EnableQuery(PageSize = 2, AllowedQueryOptions = AllowedQueryOptions.All, MaxExpansionDepth = 5)]
        [HttpGet]
        public IActionResult Get()
        {

            var l = JsonConvert.DeserializeObject<List<Valores>>("[{\"Region\":{\"Provincia\":{\"Comunidad\":{\"ID\":1184,\"Region3Desc\":\"ESPAÑA\",\"PaisID\":1184},\"ID\":1184,\"ComunidadID\":1184},\"RegionCorta\":\"ESPAÑA\"},\"ID\":12},{\"Region\":{\"Provincia\":{\"Comunidad\":{\"ID\":1184,\"Region3Desc\":\"ESPAÑA\",\"PaisID\":1184},\"ID\":1184,\"ComunidadID\":1184},\"RegionCorta\":\"ESPAÑA\"},\"ID\":13},{\"Region\":{\"Provincia\":{\"Comunidad\":{\"ID\":1184,\"Region3Desc\":\"ESPAÑA\",\"PaisID\":1184},\"ID\":1184,\"ComunidadID\":1184},\"RegionCorta\":\"ESPAÑA\"},\"ID\":12}]");

            var res = Ok(result);

            return res;
        }

Когда я запускаю этот URL ,

https://localhost: 44362 / odata / Valores ? $ Select = ID & $ expand = Region ($ select = RegionCorta; $ expand = Provincia ($ select = id, comunidadId; $ развернуть = Comunidad))

Я получаю этот результат без данных 'Comunidad'

{
    "@odata.context": "https://localhost:44362/api/$metadata#Valores(ID,Region(RegionCorta,Provincia(ID,ComunidadID,Comunidad())))",
    "value": [{
            "ID": 12,
            "Region": {
                "RegionCorta": "ESPA\u00d1A",
                "Provincia": {
                    "ID": 1184,
                    "ComunidadID": 1184
                }
            }
        }, {
            "ID": 13,
            "Region": {
                "RegionCorta": "ESPA\u00d1A",
                "Provincia": {
                    "ID": 1184,
                    "ComunidadID": 1184
                }
            }
        }
    ],
    "@odata.nextLink": "https://localhost:44362/api/Valores?$select=ID&$expand=Region%28%24select%3DRegionCorta%3B%24expand%3DProvincia%28%24select%3Did%2CcomunidadId%3B%24expand%3DComunidad%29%29&$skip=2"
}

Если раскомментировать этот код

 //options.OutputFormatters.Insert(0, new Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonOutputFormatter(
                //    new Newtonsoft.Json.JsonSerializerSettings()
                //    {
                //        MaxDepth = 10,
                //        NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
                //        Formatting = Newtonsoft.Json.Formatting.Indented
                //    },
                //    System.Buffers.ArrayPool<char>.Create(), options));

Я получу другой результат

[{
        "Region": {
            "Provincia": {
                "Comunidad": {
                    "ID": 1184,
                    "Region3Desc": "ESPAÑA",
                    "PaisID": 1184
                },
                "ID": 1184,
                "ComunidadID": 1184
            },
            "RegionCorta": "ESPAÑA"
        },
        "ID": 12
    }, {
        "Region": {
            "Provincia": {
                "Comunidad": {
                    "ID": 1184,
                    "Region3Desc": "ESPAÑA",
                    "PaisID": 1184
                },
                "ID": 1184,
                "ComunidadID": 1184
            },
            "RegionCorta": "ESPAÑA"
        },
        "ID": 13
    }
]

с данными 'Comunidad', но без информации и формата OData. Итак, я думаю, что EF-запрос в порядке, но когда формализатор Odata сериализует Value, используйте JSon default maxdeep (3).

Я видел эту ссылку, но только с newtonsoft она не работает

OData on. Net Core не возвращает правильные результаты при $ select

...