我尝试了几个 OData 包版本,例如.net5 示例项目中的 Microsoft.AspNetCore.OData 7.5.12。
因为我的真正目标是将现有的 asp.net v4 REST api 迁移到 .net6,所以我还使用 VS2022 对 .net6 和 Microsoft.AspNetCore.OData 8.0.7 进行了一些测试
虽然为这篇文章精简了基于 .net6 / Microsoft.AspNetCore.OData 8.0.7 的示例代码,但我取得了第一个成功!
现在 Swagger 站点显示了两个 GET 操作:
获取 /DynProp
和
获取 /odata/DynProp。
/odata/DynProp 操作正确显示动态属性!!!
现在我有了一个可以用于迁移的基础。下一步将是:配置路由(例如,从 Swagger 中删除非 OData 操作并为我的操作自定义 OData 路由路径)。
非常感谢您的提示和建议,帮助我不放弃。
我的工作示例代码:
控制器:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.AspNetCore.OData.Routing.Controllers;
namespace DynProp.Controllers
{
[ApiController]
[Route("[controller]")]
public class DynPropController : ODataController
{
[EnableQuery]
[HttpGet(Name = "GetDyn")]
public IEnumerable<DynProp> Get()
{
List<DynProp> list = new List<DynProp>();
DynProp obj1 = new DynProp();
obj1.Id = "TestId";
obj1.Properties.Add("key1", "value1");
obj1.Properties.Add("key2", "value2");
list.Add(obj1);
DynProp obj2 = new DynProp();
obj2.Id = "TestId2";
obj2.Properties.Add("key1", "value3");
obj2.Properties.Add("key2", "value4");
list.Add(obj2);
return list;
}
}
}
DynProp 类/EDM:
using Microsoft.OData.Edm;
using Microsoft.OData.ModelBuilder;
using System.ComponentModel.DataAnnotations;
namespace DynProp
{
public class DynProp
{
[Key]
public string Id { get; set; }
public IDictionary<string, object> Properties { get; set; }
public DynProp()
{
Id = "";
Properties = new Dictionary<string, object>();
}
}
public class TestDataModel
{
public IEdmModel GetEdmModel()
{
var odataBuilder = new ODataModelBuilder();
var classExample = odataBuilder.EntityType<DynProp>();
classExample.HasKey(s => s.Id);
classExample.HasDynamicProperties(d => d.Properties);
var entitySet = odataBuilder.EntitySet<DynProp>("DynProp");
return odataBuilder.GetEdmModel();
}
}
}
Program.cs(在 .net6 中包括 Startup.cs 的所有部分)
using DynProp;
using Microsoft.AspNetCore.OData;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers().AddOData(options =>
{
options.Select().Filter().OrderBy();
options.AddRouteComponents("odata", new TestDataModel().GetEdmModel());
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
GET /odata/DynProp 的结果:
{
"@odata.context": "https://localhost:7171/odata/$metadata#DynProp",
"value": [
{
"Id": "TestId",
"key1": "value1",
"key2": "value2"
},
{
"Id": "TestId2",
"key1": "value3",
"key2": "value4"
}
]
}