c# - 使用没有密钥的实体创建 OData API 端点
问题描述
我有一个支持 OData v4 的 ASP.NET Core API 服务。我正在尝试引入一个基于没有键的实体的控制器。OData 需要注册实体的密钥,因此是我的问题。您可以将其更多地视为一种操作方法。
这个问题不应该是 ASP.NET Core 特有的,而是想知道是否有人曾经使用 OData 成功完成过这个问题。我已经尝试在CheckRequest
模型中注册其中一个属性,但它没有说它应该是一个导航属性。我还尝试将其注册为复杂类型,因为它没有密钥,但服务随后会返回404
路由。
请参阅下面的代码示例和更多详细信息。请注意,我正在使用Microsoft.AspNetCore.App 2.1.5, Microsoft.AspNetCore.OData 7.0.1, and Microsoft.AspNetCore.OData.Versioning 3.0.0-beta1
. 在大多数情况下,我们的应用程序 OData 设置基于此处的在线示例:https ://github.com/Microsoft/aspnet-api-versioning/tree/master/samples/aspnetcore/ODataBasicSample
[ApiVersion("1.0")]
[ODataRoutePrefix("checkrequests")]
public class CheckRequestsController : ODataController
{
[HttpPost]
[ODataRoute]
public async Task<IActionResult> CheckAsync([FromBody] CheckRequest request)
{
var success = request.Values.Count == 3 && request.OtherValues.Count == 6;
return this.Ok(await Task.FromResult(new CheckResult { Success = true }));
}
}
public class CheckRequest
{
public List<int> Values { get; set; }
public List<int> OtherValues { get; set; }
}
public class CheckResult
{
public bool Success { get; set; }
}
public class CheckRequestModelConfiguration : IModelConfiguration
{
public void Apply(
ODataModelBuilder builder,
ApiVersion apiVersion)
{
switch (apiVersion.MajorVersion)
{
default:
ConfigureV1(builder);
break;
}
}
private static void ConfigureV1(ODataModelBuilder builder)
{
builder.ComplexType<V1.AccessCheckRequest>();
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddApiVersioning();
services.AddOData().EnableApiVersioning();
}
public void Configure(
IApplicationBuilder app,
VersionedODataModelBuilder modelBuilder)
{
app.UseMvc(routes =>
{
routes.MapVersionedODataRoutes("odata-bypath", "v{version:apiVersion}", modelBuilder.GetEdmModels());
});
}
}
解决方案
所以在挖掘了更多之后,我找到了答案。OData v4 支持未绑定的函数和未绑定的操作,本质上是实用程序方法。
更多文档可以在这里找到:https ://odata.github.io/WebApi/#02-03-model-builder-nonconvention在未绑定的操作和功能部分。
对上述代码示例的更改是仅更改以下部分:
public class CheckRequestModelConfiguration : IModelConfiguration
{
public void Apply(
ODataModelBuilder builder,
ApiVersion apiVersion)
{
switch (apiVersion.MajorVersion)
{
default:
ConfigureV1(builder);
break;
}
}
private static void ConfigureV1(ODataModelBuilder builder)
{
builder.AddFunction("checkrequests").Returns<CheckResult>();
}
}
推荐阅读
- android - 如何排除由于最大 Google 地图缩放而无法包含在 LatLngBounds 中的 LatLng?
- xpages - 清除重复控制
- sumo - 在 Flow 中运行 grid0 基线基准
- virtual-machine - Virturalbox 加速来宾时钟在某些操作系统上无效
- pandas - pandas 过滤值计数有多个答案
- python - 如何在发布请求中修复“从模式解析电子邮件”
- tkinter - 如何在文本文件中写入 tkinter 条目?
- android - RxJava/Android Observable 对状态变化没有反应
- vue.js - 为什么自定义分隔符 {{{}}} 在 vuejs 中不起作用?
- nested - 是否可以在 vuepress 中有子路线和路线视图?