在 JsonApiDotNetCore 中访问 IResourceService 中的字段过滤器参数

Accessing fields filter parameters in IResourceService in JsonApiDotNetCore

我目前正在尝试设置非Entity Framework 环境以通过 REST/JSON:API in ASP.NET Core 3.1 with https://github.com/json-api-dotnet/JsonApiDotNetCore

访问数据

我按照以下示例进行操作:https://github.com/json-api-dotnet/JsonApiDotNetCore/blob/master/src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs

这是我的示例方法:

public class DepartmentResourceService : IResourceService<Department>
{

    public Task<IReadOnlyCollection<Department>> GetAsync(CancellationToken cancellationToken)
    {
        IReadOnlyCollection<Department> departments = new List<Department>{
            new Department{ Id = 1, Name = "SE", Contact = "se@someaddress.at" },
            new Department{ Id = 2, Name = "SD", Contact = "sd@someaddress.at" }
        }.AsReadOnly();
        return Task.FromResult(departments);
    }

...

}

我的示例运行良好,但我还没有弄清楚如何访问给定的 JSON:API fields-filter。 但是:过滤器确实会以某种方式自动应用,并且仅发送在查询字符串中定义的给定字段,但是在生成对象 之后应用过滤器。 使用 EF 时,我可以看到 sql 查询已经限制在定义的 JSON:API fields-filter 列表中,因此该对象仅填充了请求的信息,没有其他内容。

我想在没有 EF 的情况下做同样的事情,但我缺少过滤器信息以便这样做。

我发现有一个名为 ITargetedFields (https://github.com/json-api-dotnet/JsonApiDotNetCore/blob/master/src/JsonApiDotNetCore/Resources/TargetedFields.cs/) 的接口,我想也许可以像这样将其注入构造函数:

public class DepartmentResourceService : IResourceService<Department>
{
    private readonly ITargetedFields targetedFields;

    public DepartmentResourceService(ITargetedFields targetedFields)
    {
        this.targetedFields = targetedFields;
    }
...
}

但是 ITargetedFields 的属性 AttributesRelationships 集合始终为零长度。

我在文档或示例中找不到任何内容。

有什么想法吗?

我终于找到了一个方法,如何访问字段、分页等查询信息,包括在IResourceService<TResource>:

方法AddQueryStringLayer()中有几个IQueryConstraintProvider service providers registered in JsonApiApplicationBuilder具有Scope-Lifetime:

  • IIncludeQueryStringParameterReader
  • IFilterQueryStringParameterReader
  • ISortQueryStringParameterReader
  • ISparseFieldSetQueryStringParameterReader
  • IPaginationQueryStringParameterReader
  • IResourceDefinitionQueryableParameterReader

它们由 DI 在您的 IResourceService<TResource> 实现的构造函数中注入,这是一个示例:

public class DepartmentResourceService : IResourceService<Department>
{
    private readonly ISparseFieldSetQueryStringParameterReader _sparseFieldSetQueryStringParameterReader;
    private readonly IIncludeQueryStringParameterReader _includeQueryStringParameterReader;
    private readonly ISortQueryStringParameterReader _sortQueryStringParameterReader;
    private readonly IPaginationQueryStringParameterReader _paginationQueryStringParameterReader;

    public DepartmentResourceService(
        ISparseFieldSetQueryStringParameterReader sparseFieldSetQueryStringParameterReader,
        IIncludeQueryStringParameterReader includeQueryStringParameterReader,
        ISortQueryStringParameterReader sortQueryStringParameterReader,
        IPaginationQueryStringParameterReader paginationQueryStringParameterReader
        )
    {
        _sparseFieldSetQueryStringParameterReader = sparseFieldSetQueryStringParameterReader;
        _includeQueryStringParameterReader = includeQueryStringParameterReader;
        _sortQueryStringParameterReader = sortQueryStringParameterReader;
        _paginationQueryStringParameterReader = paginationQueryStringParameterReader;
    }
    public Task<IReadOnlyCollection<Department>> GetAsync(CancellationToken cancellationToken)
    {

        // Accessing all provided information:
        IReadOnlyCollection<ExpressionInScope> constraints = _sparseFieldSetQueryStringParameterReader.GetConstraints();
        IReadOnlyCollection<ExpressionInScope> includes = _includeQueryStringParameterReader.GetConstraints();
        IReadOnlyCollection<ExpressionInScope> sortQuery = _sortQueryStringParameterReader.GetConstraints();
        IReadOnlyCollection<ExpressionInScope> pagination = _paginationQueryStringParameterReader.GetConstraints();

        // ***************************************************************
        // Do what ever you need to do, with the information provided here
        // ***************************************************************

        // Return something
        IReadOnlyCollection<Department> departments = new List<Department>{
            new Department{ Id = 1, Name = "SE", Contact = "se@someaddress.at" },
            new Department{ Id = 2, Name = "SD", Contact = "sd@someaddress.at" }
        }.AsReadOnly();
        return Task.FromResult(departments);
    }
...
}