OData v4不再扩展到第三深度之外



我的应用程序一直扩展到4个关卡,直到大约一周前,即使是样本项目的扩展也停止在第3个关卡。这里是我的OData GET方法和对应的对象模型关系,以及webApiConfig.cs文件显示MaxExpansionDepth设置为4。

我在任何地方都找不到任何帮助,所以我很感激你对这个奇怪的突然行为的建议。

[HttpGet]
[ODataRoute("RotationSets")]
public IQueryable<RotationSet> Get()
{
     var rotationSets = new List<RotationSet>()
     {
        new RotationSet()
        {
             Id = 1,
             Title = "RS 1",
             Flights = new List<Flight>()
             {
                 new Flight()
                 {
                     Id = 11,
                     StartDate = DateTime.Now,
                     EndDate = DateTime.Now.AddDays(2),
                     SpotRotations = new List<SpotRotation>()
                     {
                         new SpotRotation()
                         {
                             Id = 111,
                             Code = "123",
                             Spots = new List<Spot>()
                             {
                                 new Spot()
                                 {
                                     Id = 1111,
                                     StartDate = DateTime.Now.AddMonths(1),
                                     EndDate = DateTime.Now.AddMonths(2),
                                     Title = "Spot 1"
                                 }
                             }
                         }
                     }
                 }
             }
         }
     };
    return rotationSets.AsQueryable();
}
public class RotationSet
{
    public int Id { get; set; }
    public string Title { get; set; }
    public ICollection<Flight> Flights { get; set; }
    public RotationSet()
    {
        Flights = new List<Flight>();
    }
}
public class Flight
{
    public int Id { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public ICollection<SpotRotation> SpotRotations { get; set; }
    public Flight()
    {
        SpotRotations = new List<SpotRotation>();
    }
}
public class SpotRotation
{
    public int Id { get; set; }
    public string Code { get; set; }
    public ICollection<Spot> Spots { get; set; }
    public SpotRotation()
    {
        Spots = new List<Spot>();
    }
}
public class Spot
{
    public int Id { get; set; }
    public string Title { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
}

public static class WebApiConfig
{
    public static HttpConfiguration Configure()
    {
        // Web API configuration and services
        var config = new HttpConfiguration();
        var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
        jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        jsonFormatter.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None;
        jsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        jsonFormatter.SerializerSettings.Converters.Add(new StringEnumConverter());
        // No XML here.
        config.Formatters.Remove(config.Formatters.XmlFormatter);
        config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
        // Web API routes
        config.MapHttpAttributeRoutes();    // Must be first.
        config.EnableEnumPrefixFree(true);
        config.MapODataServiceRoute("ODataRoute", "odata", GetEdmModel());
        //routeTemplate: "api/{controller}/{id}",
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        var maxDepth = int.Parse(ConfigurationManager.AppSettings["ODataMaxExpandDepth"], CultureInfo.InvariantCulture);
        var maxNodeCount = int.Parse(ConfigurationManager.AppSettings["ODataMaxNodeCount"], CultureInfo.InvariantCulture);
        config.Filters.Add(new CacheControlAttribute());
        config.AddODataQueryFilter(new EnableQueryAttribute()
        {
            PageSize = 100, //int.Parse(ConfigurationManager.AppSettings["ODataMaxPageSize"], CultureInfo.InvariantCulture),
            MaxNodeCount = 100,
            MaxExpansionDepth = 4,
            MaxAnyAllExpressionDepth = 4,
            AllowedArithmeticOperators = AllowedArithmeticOperators.None,
            AllowedFunctions = AllowedFunctions.AllFunctions,
            AllowedQueryOptions = AllowedQueryOptions.Count |
                                  AllowedQueryOptions.Expand |
                                  AllowedQueryOptions.Filter |
                                  AllowedQueryOptions.OrderBy |
                                  AllowedQueryOptions.Select |
                                  AllowedQueryOptions.Skip |
                                  AllowedQueryOptions.Top |
                                  AllowedQueryOptions.Format
        });
        return config;
    }
    private static IEdmModel GetEdmModel()
    {
        var builder = new ODataConventionModelBuilder();
        builder.EntitySet<RotationSet>("RotationSets");
        builder.EnableLowerCamelCase();
        return builder.GetEdmModel();
    }
}

我修复了这个问题,将所需的元素添加到EDM模型中,不确定这是否是一个错误(OData),但我认为,当我们需要自动扩展或扩展超过3个级别时,它不会让我们这样做,除非我们添加那些未显示的实体(或更好地添加它们)作为EDM模型配置的一部分。例如:

builder.EntitySet<Spot>("Spots");

我还注意到,如果你像我一样使用自动展开,你还需要这样做:

builder.EntitySet<RotationSet>("RotationSets").EntityType.Count().Select().Filter().OrderBy().Page().Expand(Microsoft.AspNet.OData.Query.SelectExpandType.Automatic, 0);//0 disable the max check
builder.EntitySet<SpotRotation>("SpotRotations").EntityType.Count().Select().Filter().OrderBy().Page().Expand(Microsoft.AspNet.OData.Query.SelectExpandType.Automatic, 0);//0 disable the max check

你也可以用:

修饰控制器
[EnableQuery(MaxExpansionDepth = 0)]

希望对你有帮助。

谢谢

在Controller Action上使用Enable Query来覆盖max depth…

[EnableQuery(MaxExpansionDepth = 23)]
[HttpGet]
[ODataRoute("RotationSets")]
public IQueryable<RotationSet> Get() { ... }

最新更新