使用TFS2018 API迁移XAML构建定义源映射失败问题咨询
解决TFS 2018 API更新TFVC源映射未生效的问题
首先明确:TFS 2018的Build API是支持更新TFVC源映射的,你的问题出在细节处理上,而非API本身不支持。下面拆解问题并给出修正方案:
1. 先确认目标构建定义的仓库类型
如果要更新的构建定义仓库类型不是TFVC,设置tfvcMapping属性完全不会生效。你需要先强制指定仓库类型:
if (def.Repository.Type != "TfsVersionControl") { def.Repository.Type = "TfsVersionControl"; }
2. 修正LocalPath的格式问题
你当前生成的localPath用的是转义后的反斜杠\\Utils\\TestQueue,但TFS API更倾向于使用正斜杠/作为路径分隔符,且不需要开头的根斜杠(因为默认根映射已经是\)。
建议在序列化前就调整映射对象的路径:
foreach (var mapping in mappings) { // 替换反斜杠为正斜杠,移除$(SourceDir),并去掉开头的冗余斜杠 mapping.localPath = mapping.localPath.Replace("\\", "/") .Replace("$(SourceDir)", "") .TrimStart('/'); }
调整后生成的JSON中localPath会变成Utils/TestQueue,更符合TFS的预期格式。
3. 修复异步调用的阻塞问题
你用t.Result同步阻塞异步调用,可能会导致线程死锁,或者API调用未完全完成就结束。建议改用await(如果在异步方法中),或者用.GetAwaiter().GetResult()替代:
using (var buildClient = new BuildHttpClient(uri, cred)) { // 异步等待API调用完成 var result = await buildClient.UpdateDefinitionAsync(def, teamProject); // 非异步方法下的替代写法: // var result = buildClient.UpdateDefinitionAsync(def, teamProject).GetAwaiter().GetResult(); }
完整修正后的代码示例
var def = defs.FirstOrDefault(d => d.Name == xamlDef.Name); if (def != null) { // 确保仓库类型为TFVC if (def.Repository.Type != "TfsVersionControl") { def.Repository.Type = "TfsVersionControl"; } // 预处理映射路径格式 foreach (var mapping in mappings) { mapping.localPath = mapping.localPath.Replace("\\", "/") .Replace("$(SourceDir)", "") .TrimStart('/'); } var json = JsonConvert.SerializeObject(mappings); def.Repository.Properties["tfvcMapping"] = json; using (var buildClient = new BuildHttpClient(uri, cred)) { var result = await buildClient.UpdateDefinitionAsync(def, teamProject); } }
额外验证点
如果调整后还是不生效,可以手动调用TFS的Rest API(GET https://{tfs-url}/_apis/build/definitions/{definitionId}?api-version=4.1)查看当前构建定义的repository.properties结构,确认你的JSON格式和官方返回的结构完全一致。
内容的提问来源于stack exchange,提问作者doorman
相关产品推荐
相关产品推荐

