【问题标题】:OData Alternate Key configuration with aspnet core 3.1 endpoint routing带有 aspnet 核心 3.1 端点路由的 OData 备用密钥配置
【发布时间】:2020-05-19 12:12:55
【问题描述】:

我正在尝试配置 ODATA 备用密钥,同时使用 ODATA V7、Aspnet Core 3.1 和端点路由。看来我在某处错过了配置步骤。

我认为我需要配置一个 AlternateKeysODataUriResolver,但是对于端点路由,我还没有找到我需要这样做的地方。

我的代码如下:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{


    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapBlazorHub();
        endpoints.Select().Filter().OrderBy().Count().MaxTop(20);
        endpoints.MapODataRoute("api", "api", GetEdmModel());
        endpoints.MapFallbackToPage("/_Host");
    });
}

IEdmModel GetEdmModel()
{
    var odataBuilder = new ODataConventionModelBuilder();
    odataBuilder.EntitySet<DatabaseClaim>("DatabaseClaims");
    odataBuilder.EntitySet<EmployeeClaim>("EmployeeClaims");
    odataBuilder.EntitySet<Employee>("Employees");
    odataBuilder.EntitySet<Department>("Departments");

    var model = odataBuilder.GetEdmModel();

    //Add alternate key: find entity type, find property, add alternate key def
    IEdmEntityType employeeType = model.FindDeclaredEntitySet("Employees").EntityType();
    var userid = employeeType.FindProperty("UserId");
    ((EdmModel)model).AddAlternateKeyAnnotation(employeeType, new Dictionary<string, IEdmProperty> {
        {
            "UserId", userid
        }
    });

    return model;
}

然后在我的 odata 控制器中我有

[EnableQuery]
[ODataRoute("{id}")]
public async Task<IActionResult> Get(Guid id)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    };

    var record = await Context.Employees.FindAsync(id);
    if (record == null)
    {
        return NotFound();
    }
    return Ok(record);
}

[EnableQuery]
[ODataRoute("Employees(UserId={userid})")]
public async Task<IActionResult> GetByUserId([FromODataUri] string userid)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    };

    var record = await Context.Employees
        .FirstOrDefaultAsync(r => r.UserId == userid);
    if (record == null)
    {
        return NotFound();
    }
    return Ok(record);
}

【问题讨论】:

    标签: asp.net-core odata


    【解决方案1】:

    @斯科特

    希望下面的代码可以帮助到你?

        app.UseEndpoints(endpoints =>
        {
                ...
                endpoints.MapODataRoute("odata", "odata",
                        builder =>
                            builder.AddService(ServiceLifetime.Singleton, sp => model)
                                .AddService<IEnumerable<IODataRoutingConvention>>(ServiceLifetime.Singleton, sp =>
                                    ODataRoutingConventions.CreateDefaultWithAttributeRouting("odata", configuration))
                                .AddService<ODataUriResolver>(ServiceLifetime.Singleton, sp => new AlternateKeysODataUriResolver(model)));
       ...
    }
    

    【讨论】:

    • 谢谢,它让我更接近了,但我被配置参数卡住了,这是一个 IRouteBuilder 吗?我在哪里可以获得它的实例。
    【解决方案2】:

    Sam Xu 的回答是正确的,你必须像这样映射 OData 路由,但它不能工作,因为你没有 HttpConfiguration(配置变量)。

    对于端点路由,请改用endpoints.ServiceProvider

    我在这里为你写了一个例子:

    var model = GetEdmModel();
    app.UseEndpoints(endpoints =>
    {
        ...
        endpoints.MapODataRoute("odata", "odata", builder => builder
            .AddDefaultODataServices()
            .AddService(Microsoft.OData.ServiceLifetime.Singleton, s => model)
            .AddService<IEnumerable<IODataRoutingConvention>>(Microsoft.OData.ServiceLifetime.Singleton, sp => ODataRoutingConventions.CreateDefaultWithAttributeRouting("odata", endpoints.ServiceProvider))
            .AddService<ODataUriResolver>(Microsoft.OData.ServiceLifetime.Singleton, s => new AlternateKeysODataUriResolver(model) { EnableCaseInsensitive = true })
        );
    });
    

    请注意,我在 ODataUriResolver 中另外设置了 EnableCaseInsensitive = true 以使用不区分大小写的路由前缀。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-10
      • 1970-01-01
      • 2020-04-25
      • 2020-11-17
      • 2019-04-04
      • 2020-10-11
      • 1970-01-01
      • 2020-09-09
      相关资源
      最近更新 更多