将 sap.ui.table.Table 的行绑定到 sap.ui.model.odata。v2.ODataModel 的方法 - url 中缺少参数

Bind sap.ui.table.Table's rows to sap.ui.model.odata.v2.ODataModel's method - parameter is missing from url

也许不需要告诉你,我一直在谷歌搜索、查看文档和规范,并测试了几天但没有成功。

我想要实现的目标: 我想将 table 的行绑定到模型,但对于同一模型中的服务方法,它接受参数、过滤 Contragents 和 returns 一个 IQueryable。我记得昨天阅读了一个 Whosebug 问题——有人问是否可以仅使用 OData url 参数来实现 sql 'in' 子句。他们回答说,唯一的方法是构建一个 $filter=(Name eq 'test1' and Name eq 'test2' and ...) 形式的字符串。所以我认为如果我可以向我的 OData 服务添加一个自定义方法会很好,这样我就可以在 C# 中舒适地使用 LINQ。我在 OData 文档中看到,可以不请求模型的实体,而是通过编写正确的 URL 再次查询来自这种方法的数据。所以基本上,这就是我想要的 - 使用我创建的 OData 服务将我的 SAP table 绑定到 select * from Contragent where Name in (select Name from ...)

到目前为止我所做的: 首先,我学习了如何向 OData 服务添加自定义服务方法。看起来它必须放在初始化服务的同一个 class 中:

public class MyService : EntityFrameworkDataService<MyEntities>
{
    // This method is called only once to initialize service-wide policies.
    public static void InitializeService(DataServiceConfiguration config) {
        // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
        // Examples:
        config.SetEntitySetAccessRule("*", EntitySetRights.AllRead | EntitySetRights.AllWrite);
        //https://debugmode.net/2012/01/13/how-to-work-with-custom-method-in-wcf-data-service/
        config.SetServiceOperationAccessRule("*", ServiceOperationRights.All); // for the custom method to be accessible via the service
        config.UseVerboseErrors = true;
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
    }

    private MyEntities entities = new MyEntities();
    //https://docs.microsoft.com/en-us/dotnet/framework/data/wcf/service-operations-wcf-data-services
    [WebGet] // this attribute is required - ^see the link above^
    public IQueryable<Contragent> GetContragentsByIsContained(int isContained)
    {
        IQueryable<Contragent> result = entities.Contragent;
        List<string> neededNames = GetNeededNames();
        if (isContained == 0)
        {
            result = result.Where(x => !neededNames.Contains(x.Name));
        }
        else if (isContained == 1)
        {
            result = result.Where(x => neededNames.Contains(x.Name));
        }
        // else - no filtering

        return result;
    }
}

之后,我做了一些测试,发现 URLs http://localhost:port/Services/MyService.svc/GetContragentsByIsContained?isContained=1http://localhost:port/Services/MyService.svc/GetContragentsByIsContained?isContained=0 都运行良好。 之后,我尝试

.bindRows({
    path: '/GetContragentsByIsContained?isContained=' + (typeof (isContained) === 'string' && isContained !== '' ? isContained: 2));
    //...
});

我的 table 对此结果无效。

打开 Fiddler 查看发生了什么,告诉我问题出在哪里。我看到,SAP UI 5 发送了以下请求:400 HTTP localhost:port/Services/MyService.svc/GetContragentsByIsContained400 HTTP localhost:port/Services/MyService.svc/GetContragentsByIsContained?$skip=0&$top=25。我一点也不惊讶,服务器 400 对他们来说,因为......嘿,SAP,isContained 参数去哪儿了!? 这让我在 Fiddler 或浏览器中做了另一个测试——没关系:http://localhost:port/Services/MyService.svc/GetContragentsByIsContained?isContained=1&$filter=(Name eq 'Test123')。有一个名为 Test123 的 Contragent,它在所需的名称中,所以这个查询 isContained=1 returns 1 item 应该是,而 isContained=0 returns no items - 再次符合预期.因此,UI5 库将以 $ 开头的特殊参数附加到我的 URL 的末尾应该不是问题,而无需删除我的参数 isContained。

所以,最后,问题本身: SAP 库在加载数据之前删除绑定路径中 ? 之后的所有内容是否正常?我怎样才能保留这个参数?提前致谢!

编辑:我忘了告诉你,我试着添加

urlParameters: {
    "isContained": (typeof (isContained) === 'string' && isContained !== '' ? isContained : 2 )
}

就像我想做一个 read():

model.read("/GetContragentsByIsContained" {
    urlParameters: {
        "isContained": (typeof (isContained) === 'string' && isContained !== '' ? isContained : 2 )
    },
    success: function (count, args) {
        debugger;
        table.rows = count.results; // this doesn't work as well
    },
    error: function (args) {
        debugger;
        console.log(args);
    }
});

没用。

您可以在下面的 XML 视图中找到声明性聚合绑定的有效语法:

items="{
    path: '/MySuperSet',
    parameters: {
        custom: {
            foo: 'bar'
        }
    }
}"

请注意,无法传递以“$”开头的自定义参数。见 ODataListBinding class.