OData v4停止扩展超过第3深度

时间:2016-11-08 07:52:14

标签: odata expand

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

我无法在任何地方找到任何帮助,所以我很感激你对这种奇怪的突然行为的投入。

[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();
    }
}

2 个答案:

答案 0 :(得分:0)

在Controller Action上使用Enable Query覆盖最大深度...

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

答案 1 :(得分:0)

我解决了此问题,将所需的元素添加到EDM模型中,不确定是否是bug(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)]

希望这会有所帮助。

谢谢