Я использую пакет 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
- Для этой проблемы существует настройка репо-источника: репо