Microsoft.AspNet.OData [EnableQueryAttribute] 与 [Route] 属性结合



我正在使用 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 操作适用于所有查询,但如果存在路由属性,则当每个 I 用户都使用评估"any"语句的筛选器时,我会收到以下异常。

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

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

注意:

  • 这可能是 odata 中的一个错误,请参阅:1471
  • 此问题有一个源存储库设置:存储库

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

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

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

最新更新