具有 .NET 6 和 NewtonSoft 以及自定义查询属性的 OData 在短时间内停止工作
我一直在 .NET 6 Blazor 客户端/服务器应用程序上尝试使用 OData,但我现在注意到,在很短的时间(可能 10 或 20 分钟)后,OData 在启用 OData 的端点上完全停止工作。刷新 Swagger doco 或端点路由不会执行任何操作,但刷新主站点似乎会再次启动它。
这就是我连接它的方式,因为我还使用 NewtonSoft 作为 JsonPatch:
var maxTop = Configuration.GetValue<int>("ODataOptions:MaxTop");
services
.AddControllers(options => options.Filters.Add<ApiExceptionFilterAttribute>())
.AddOData(options => options.Select().Filter().OrderBy().Expand().SetMaxTop(maxTop))
.AddODataNewtonsoftJson();
然后我只在路由上使用 EnableQuery 属性,但实际上我已经使用以下自定义属性扩展了它:
public class CustomEnableQueryAttribute : EnableQueryAttribute
{
public CustomEnableQueryAttribute()
{
// override the page size using what's in config
PageSize = Startup.Configuration.GetValue<int>("ODataOptions:PageSize");
}
// Throw an exception that can be handled in the Api Exception Filter
public override void ValidateQuery(HttpRequest request, ODataQueryOptions queryOptions)
{
try
{
base.ValidateQuery(request, queryOptions);
}
catch (Exception ex)
{
throw new ODataQueryValidationException(ex.Message);
}
}
}
所以说我只想测试返回 id:api/v1/entities?%24select=id 它工作正常,但 10 或 20 分钟后,我返回并刷新页面,然后它再次返回具有所有属性的所有实体;没有 OData 路由工作。即使在Swagger中,同样的行为,没有错误,就像EnableQuery或绕过一样?
这是控制器:
[ApiController]
[CustomApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public class MyController : ApiControllerBase
{
[HttpGet]
[CustomEnableQuery]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IList<Dto>>> Get()
{
return Ok(await Mediator.Send(new GetQuery()));
}
}
对于这里可能发生的情况有什么建议吗?我应该只使用 EdmModel 而不是 EnableQuery 属性吗?
I've been experimenting with OData on a .NET 6 Blazor Client/Server app but I've now noticed that after a short period of time (maybe 10 or 20 minutes), OData just stops working at all on my OData enabled endpoints. Refreshing the Swagger doco or the endpoint route doesn't do anything, but refreshing the main site seems to kick it off again.
This is how I'm hooking it up, as I'm also using NewtonSoft for JsonPatch:
var maxTop = Configuration.GetValue<int>("ODataOptions:MaxTop");
services
.AddControllers(options => options.Filters.Add<ApiExceptionFilterAttribute>())
.AddOData(options => options.Select().Filter().OrderBy().Expand().SetMaxTop(maxTop))
.AddODataNewtonsoftJson();
And then I just use the EnableQuery attribute on routes, but I've actually extended it with the following custom attribute:
public class CustomEnableQueryAttribute : EnableQueryAttribute
{
public CustomEnableQueryAttribute()
{
// override the page size using what's in config
PageSize = Startup.Configuration.GetValue<int>("ODataOptions:PageSize");
}
// Throw an exception that can be handled in the Api Exception Filter
public override void ValidateQuery(HttpRequest request, ODataQueryOptions queryOptions)
{
try
{
base.ValidateQuery(request, queryOptions);
}
catch (Exception ex)
{
throw new ODataQueryValidationException(ex.Message);
}
}
}
So say I just want to test returning the id's: api/v1/entities?%24select=id
It works fine, but then after 10 or 20 minutes, I go back and refresh the page, and then it returns me all entities with all properties again; no OData routes work. Even in Swagger, the same behaviour, no errors, just as if the EnableQuery or circumvented?
Here is the controller:
[ApiController]
[CustomApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public class MyController : ApiControllerBase
{
[HttpGet]
[CustomEnableQuery]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IList<Dto>>> Get()
{
return Ok(await Mediator.Send(new GetQuery()));
}
}
Any suggestions on what might be happening here? Should I just use the EdmModel rather than the EnableQuery attributes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,我想我已经解决了这个问题。我想让操作保持一致,并且全部返回 ActionResult,因此将列表包装在 OK() 方法中。
但是,当我删除它并仅返回 IList 时,OData 到目前为止似乎可以正常工作。
再次通读一遍,我可以看到它应该可以工作,并且我的目标应该是返回一个 IQueryable: https://learn.microsoft.com/en-us/odata/webapi/first-odata-api
返回 System.Linq.IQueryable 或 ActionResult 启用 OData使用 ef 核心功能将查询转换为 SQL 查询。返回其他类型(例如 IEnumerable)会导致 OData 在应用程序中执行查询。
但是,即使使用 IQueryable 并用 ActionResult 包装时,它似乎对我不起作用。
Ok, I think I've worked out the problem. I wanted to make the Actions consistent, and all return ActionResult, so wrapped the list in an OK() method.
However, when I removed that and only return the IList, OData seems to work without fail so far.
Reading through this again, I can see it should work, and I should be aiming to return an IQueryable: https://learn.microsoft.com/en-us/odata/webapi/first-odata-api
Returning System.Linq.IQueryable or ActionResult enables OData to translate queries to SQL queries using ef core capabilities. Returning other types such as IEnumerable causes OData to perform queries in the app.
However, even when using IQueryable and wrapping with ActionResult it didn't seem to work for me.