TFS Rest API:扩展数据服务不可靠吗?

时间:2017-05-21 15:28:35

标签: tfs tfs2015 azure-devops-rest-api

由于意外的扩展数据服务行为而未获得所需的首选项,因此我的TFS中心扩展(内部部署2015.3)无法正确加载。扩展用户存储 - 在首次启动/加载集线器页面后安装一次 - 集合级别的扩展首选项,作为键值对(来自扩展数据服务API的getValue / setValue),以及如果重新加载集线器页面偏好已存储。它就像我的集线器页面中的应用程序向导/首次启动对话框。

但是,当我在同一个TFS的另一个集合上安装扩展并希望为该集合存储(= setValue)首选项时,它会返回OK(可以在F12-> Internet Explorer的网络捕获中看到它),但是刷新(键上的getValue)我的集线器时找不到这些先前输入/存储的键值对。它为密钥提供空值,并且"首先启动"对话框再次出现,如果有一个键的值,应该发生什么。已经调试过,它总是在该集合中返回空(空值)。服务没有错误,没有捕获,没有调试。

我可以在其他地方(在TFS日志,事件查看器或数据库上)查看更深入的调试吗?

我还尝试使用Powershell和restcalls手动,通过在扩展数据服务的Rest URL上放置和获取json。在一个集合中,它可以工作(手动和每个集线器扩展),但对于另一个集合,数据服务不起作用。

2015.3扩展数据服务中是否存在已知问题?如果我无法将扩展的首选项存储在任何地方,我真的有问题 - 将其存储到默认的源控制路径是一种替代方案,但我不想强制项目为我的扩展程序登记首选项... < / p>

编辑: 添加相关代码段

function showSourceControlDialog(project: string/*TFS_Core_Contracts.TeamProjectReference*/) {
    return Q.Promise(function (resolve, reject) {
        //setTimeout(function () {
        var thatProjectIDclean = project/*.id*/.replace(/-/g, "_");
        var enterSourceControlPathDialog = VSS_Controls_Dialogs.show(VSS_Controls_Dialogs.ModalDialog, {
            title: "Please now enter source control path for " + thisProjectName /*project.name*/,
            content: $("<p/>").addClass("confirmation-text").html("<label><b>Source Control Path</b> to preferences file, e.g. '$/" + thisProjectName /*thisCollectionName + "/" + project.name*/ + "/.../...xml:</label><input id='enterSourceControlPathInput' size='40'/>" /*+ projectName + ".xml"*/),
            useBowtieStyle: true,
            buttons: {
                "Cancel": function () {
                    enterSourceControlPathDialog.close();
                    enterSourceControlPathDialog.dispose();
                    reject("cancelled");
                },
                "OK": function () {
                    sourceControlPath = $("input#enterSourceControlPathInput").val();
                    if (sourceControlPath) {
                        setConfiguration(thatProjectIDclean, sourceControlPath).then(function (setToThisPath) {
                            console.log(setToThisPath);
                            enterSourceControlPathDialog.close();
                            enterSourceControlPathDialog.dispose();
                            $(".bss-button").show();
                            $(".bss-tvc").show();
                            resolve(sourceControlPath);
                        }).catch(function (error) {
                            reject(error);
                        })
                    }
                }
            }
        });
        //}, 10000);
    });
}

function setConfiguration(key: string, value: string) {
    return Q.Promise(function (resolve, reject) {
        // Get data service
        VSS.getService(VSS.ServiceIds.ExtensionData).then(function (dataService: IExtensionDataService) {
            // Set value in collection scope
            dataService.setValue(pssVersion + "_" + key, value/*, { scopeType: "Project Collection" }*/).then(function (setToThis: string) {
                console.log(pssVersion + "_" + key + " is now " + setToThis );
                resolve(setToThis);
            }, function (error) {
                reject(error);
                console.log(error);
        }, function (error) {
            reject(error);
            console.log(error);
        });
    });
}

function getConfiguration(key: string) {
    return Q.Promise(function (resolve, reject) {
        // Get data service
        VSS.getService(VSS.ServiceIds.ExtensionData).then(function (dataService: IExtensionDataService) {
            // Get value in collection scope
            dataService.getValue(pssVersion + "_" + key/*, { scopeType: "Project Collection" }*/).then(function (gotThis: string) {
                sourceControlPath = gotThis;
                console.log(pssVersion + "_" + key + " is " + gotThis );
                resolve(gotThis);
            }, function (error) {
                reject(error);
                console.log(error);
            });
        }, function (error) {
            reject(error);
            console.log(error);
        });
    });
}

try {
    console.log(thisProjectIDclean);
    getConfiguration(thisProjectIDclean).then(function (resultPath: string) {
      console.log(resultPath);
    console.log(sourceControlPath);
    if (!resultPath) {
            //getProjects().then(function (resultProjects: TFS_Core_Contracts.TeamProjectReference[]) {
            //    resultProjects.forEach(function (resultProject: TFS_Core_Contracts.TeamProjectReference) {
                    showSourceControlDialog(thisProjectID/*resultProject*/).then(function () {
                        getXMLTree();
                    }, function (error) {
                        console.log(error);
                    });
            //    }, function (error) {
            //        console.log(error);
            //    });
            //}, function (error) {
            //    console.log(error);
            //});
        } else {
            getXMLTree();
        }
    });
} catch (error) {
    console.log(error);
}

1 个答案:

答案 0 :(得分:0)

不幸的是,你想做的事情是不可能的。参考example“最大”范围,您可以存储扩展数据是“项目集合”。 根据我在使用ExtensionDataService时的经验,无法从“外部”集合中查询数据。