angular - 为 Angular SPA 应用程序结合 OData 和 .NET API
问题描述
我正在创建一个项目,该项目将具有与 .net 核心 Web Api 项目对话的 Angular 前端,使用 OData 提供丰富的查询。我已将 OData Nuget 包添加到我的 Angular 项目中。
我遵循了以下教程: https ://devblogs.microsoft.com/odata/simplifying-edm-with-odata/
在我的Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
/* snipped some code about DbContext and AutoMapper, not relevant */
services.AddMvcCore(action => action.EnableEndpointRouting = false)
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddOData();
services.AddODataQueryFilter();
}
private static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.EntitySet<Asset>("Assets");
return builder.GetEdmModel();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseMvc(routes =>
{
routes.EnableDependencyInjection();
routes.Select().Filter().OrderBy().Expand().Count().MaxTop(10);
routes.MapODataServiceRoute("api", "api", GetEdmModel());
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
在我的API 控制器类中(这里称为“资产”)
public class AssetsController : ControllerBase
{
public AssetsController(IAssetService _service)
{
this._service = _service;
}
[HttpGet("[action]")]
[EnableQuery()]
public ActionResult<IEnumerable<Asset>> All()
{
var assets = _service.GetAllAssets();
return assets.ToList();
}
}
问题 1
如果我从 Web API Controller 类中删除 ApiController 属性,则 URL http://localhost:xxxx/api/Assets/All只会再次呈现我的 SPA。
[Route("api/[controller]")]
[ApiController]
问题 2
如果我再次将此代码添加到我的班级,则会发生以下情况:
调用http://localhost:xxxx/api/Assets ?$count=true 应该返回如下列表:
{
"@odata.context": "https://localhost:44374/api/$metadata#Assets",
"@odata.count": 2,
"value": [
{
"Id": "9cef40f6-db31-4d4c-997d-8b802156dd4c",
"Name": "Asset 1",
},
{
"Id": "282be5ea-231b-4a59-8250-1247695f16c3",
"Name": "Asset 2",
}
]
}
但相反,此端点返回:
[
{
"Id": "9cef40f6-db31-4d4c-997d-8b802156dd4c",
"Name": "Asset 1",
},
{
"Id": "282be5ea-231b-4a59-8250-1247695f16c3",
"Name": "Asset 2",
}
]
有谁知道发生了什么或我做错了什么?
解决方案
我在您的代码中看到的是您正在使用服务获取所有资产,但这不是您的上下文,是吗?OData 端点需要返回一个上下文来对抗使用一些黑魔法。
我不喜欢它,但我相信如果你想以你尝试的方式使用 OData,你需要将你的上下文注入你的控制器
推荐阅读
- jquery - 我遇到的问题是使用 laravel5.8 在 jquery 克隆中存储图像字段数据
- shell - 为什么退出在功能命令中不起作用如何使其工作?
- css - 如何修复谷歌浏览器中奇怪的字体渲染(一些更高的字符)?
- excel - 如何通过应用模块来更改工作表中的代码
- java - 查找数组中数字的次数
- ansible - 无法翻译主机名——Ansible/AWX
- css - 使用 CSS 识别定位器
- java - 是否可以使用仅在使用此枚举时定义的变量创建枚举?
- java - ProtoBuf Message Over Mqtt 订阅者问题
- html - Html 表格在 Internet Explorer 上不起作用