Microsoft.AspNet.OData [EnableQueryAttribute] завершается ошибкой в ​​сочетании с атрибутом [Route] - PullRequest
0 голосов
/ 09 июня 2018

Я использую пакет nuget Microsoft.AspNet.OData 6.1.0.создать действие с включенными оддатами.Я столкнулся с проблемой с атрибутом [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 будет работать для всех запросов, но если атрибут route присутствует, я получаюследующее исключение, когда каждый пользователь I использует фильтр, который оценивает оператор 'any'.

{
  "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()"
}

Что я делаю не так?В этом простом примере атрибут route не является необходимым, но в моей реальной ситуации это имеет значение.

Примечание:

  • Это может быть ошибка в odata, см .: 1471
  • Для этой проблемы существует настройка репо-источника: репо

1 Ответ

0 голосов
/ 10 июля 2018

Оказывается, была ошибка, связанная с атрибутом DataContract, который был исправлен в версии 7.0.0

Запрос на извлечение, который исправил ошибку: https://github.com/OData/WebApi/pull/1484

Версия Nuget с исправлением ошибки: https://www.nuget.org/packages/Microsoft.AspNet.OData/7.0.0

...