与[Route]属性结合使用时,Microsoft.AspNet.OData [EnableQueryAttribute]失败

时间:2018-06-09 00:07:13

标签: asp.net-web-api odata

我使用的是nuget包Microsoft.AspNet.OData 6.1.0。创建启用odata的操作。我在以下设置中遇到了[Route]属性的问题。

    // The Setup 
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // configure non odata ...

            //OData support
            config.AddODataQueryFilter();
            config.EnableDependencyInjection();

            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            builder.EnableLowerCamelCase(NameResolverOptions.ProcessReflectedPropertyNames | NameResolverOptions.ProcessExplicitPropertyNames);

            builder.EntitySet<MixedRealityCatalogItem>("KISS");

            var edmModel = builder.GetEdmModel();

            config.MapODataServiceRoute("ODataRoute", "/", edmModel);

            config.Count().Filter().OrderBy().Select().MaxTop(2000);
        }
    }


   // The Controller
    public class KISSController : ApiController
    {
        public KISSController(IRepository<MixedRealityCatalogItem> repository)
        {
            this.Repository = repository ?? throw new ArgumentNullException(nameof(repository));
        }

        private IRepository<MixedRealityCatalogItem> Repository { get; set; }

        [EnableQuery(PageSize = 2000, MaxAnyAllExpressionDepth = 2)]
        [HttpGet]
        [Route("KISS")] // <-- this causes and exception
        public IEnumerable<MixedRealityCatalogItem> GetAll(ODataQueryOptions<MixedRealityCatalogItem> options)
        {

            IQueryable<MixedRealityCatalogItem> results = this.Repository.GetAll();

            var settings = new ODataQuerySettings
            {
                HandleNullPropagation = HandleNullPropagationOption.False,
                EnableConstantParameterization = false,
                EnsureStableOrdering = false
            };
            //Builds, but does not execute the Iqueryable
            IQueryable finalQuery = options.ApplyTo(results, settings);

            var finalResults = new List<MixedRealityCatalogItem>();

            //Will actually execute the query against the DB
            foreach (MixedRealityCatalogItem item in finalQuery)
            {
                finalResults.Add(item);
            }
            return finalResults;
        }
    }

如果我注释掉Route属性,GetAll操作适用于所有查询,但是如果存在路由属性,当我每个用户都使用一个过滤器来评估一个&#39; any&#39;言。

{
  "Message": "An error has occurred.",
  "ExceptionMessage": "Value cannot be null.\r\nParameter name: type",
  "ExceptionType": "System.ArgumentNullException",
  "StackTrace": "   at System.Linq.Expressions.Expression.Parameter(Type type, String name)\r\n   at System.Web.OData.Query.Expressions.FilterBinder.HandleLambdaParameters(IEnumerable`1 rangeVariables)\r\n   at System.Web.OData.Query.Expressions.FilterBinder.BindAnyNode(AnyNode anyNode)\r\n   at System.Web.OData.Query.Expressions.FilterBinder.BindExpression(SingleValueNode expression, RangeVariable rangeVariable, Type elementType)\r\n   at System.Web.OData.Query.Expressions.FilterBinder.BindFilterClause(FilterBinder binder, FilterClause filterClause, Type filterType)\r\n   at System.Web.OData.Query.FilterQueryOption.ApplyTo(IQueryable query, ODataQuerySettings querySettings)\r\n   at System.Web.OData.Query.ODataQueryOptions.ApplyTo(IQueryable query, ODataQuerySettings querySettings)\r\n   at AssetManager.Api.Controllers.Contracts.KISSController.GetAll(ODataQueryOptions`1 options) in D:\\git\\LSource\\AssetManagerAPI\\src\\AssetManager.Web\\Controllers\\Contracts\\AssetManagerBaseApiController.cs:line 48\r\n   at lambda_method(Closure , Object , Object[] )\r\n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)\r\n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.AuthenticationFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}

我做错了什么?在这个简单的例子中,路由属性不是必需的,但在我的实际情况中,这很重要。

注意:

  • 这可能是odata中的一个错误,请参阅:1471
  • 针对此问题设置了源代码设置:repo

1 个答案:

答案 0 :(得分:0)

事实证明,存在与DataContract属性相关的错误,该错误已在7.0.0版中修复

拉出修正错误的请求:https://github.com/OData/WebApi/pull/1484

修复错误的Nuget版本:https://www.nuget.org/packages/Microsoft.AspNet.OData/7.0.0