如何在使用C# BOT Framework SDK V4 构建的瀑布对话框中调用AZURE DEVOPS rest API?
How to call AZURE DEVOPS rest API in the water fall dialog built using C# BOT Framework SDK V4?
我使用 BOT Framework SDK V4 通过 C# 创建了网络频道聊天机器人。它有多个瀑布对话框,根据在主对话框中选择的选项执行一组操作。
在其中一个对话框中,我的要求是用户输入一些数据,然后使用它我应该在我的 AZURE DEvOps 项目中创建一个类型任务的工作项以用于跟踪目的。我能够成功地从用户那里获取数据,但是在 devops 中创建 WORK ITEM 时我遇到了问题。我已经从我这边尝试了一些事情,但如果通过创建单独的 C# 控制台应用程序来执行,它们就可以工作,但是如果我尝试通过安装相关的 NuGET 包或添加参考程序集来使用相同的代码,我会收到错误或警告。
尝试一:在BOTCode中使用TFS相关的nuget包:
如果我尝试通过安装与 TFS Extended 客户端相关的 Nuget 包来使用代码,那么在安装过程中它会显示兼容性警告和我的参考程序集部分有一个警告符号。虽然我还没有尝试在我的对话框 class 中执行这段代码,因为虽然它可能有效,但我不确定在发布到 AZURE 后它是否会导致问题。
现在来试试2
尝试 2:在 BOT 代码中使用 AZURE DEVOPS REST API:
我已经编写了用于调用 REST API 的代码,因为我在我的对话框中使用了以下代码 class:
string token = "toekn";
string type = "Task";
string organization = org
string project = "Project";
int workitemid = 0;
string url = $"https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/${type}?api-version=5.0";
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(new object[]{new
{
op = "add",
path = "/fields/System.Title",
value = "Testing Workitem creation through API"
},
new {
op = "add",
path = "/fields/System.Description",
value = "Model Request ID#" + requestid + " from: "+ name + " requested from ChatBot"
},
new {
op = "add",
path = "/fields/Priority",
value = 1
}
});
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", token))));
var method = new HttpMethod("POST");
var request = new HttpRequestMessage(method, url)
{
Content = new StringContent(json, Encoding.UTF8,
"application/json-patch+json")
};
var sendresult = client.SendAsync(request).Result;
var result = sendresult.Content.ReadAsStringAsync().Result;
Console.WriteLine("Completed!");
dynamic workitemdata = JsonConvert.DeserializeObject(result);
workitemid = workitemdata.id;
};
现在如果你在上面的代码中观察到有一个方法 -
JavaScriptSerializer 序列化程序 = new JavaScriptSerializer();
这需要一个名为 system.web.extensions.dll 的程序集引用才能使用 我已经通过浏览此 DLL 添加了此引用,即
使用 System.Web.Script.Serialization;
现在当我执行这个时,我得到如下异常:
捕获到异常: 无法加载文件或程序集 'System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'。不应为执行加载引用程序集。它们只能在仅反射加载器上下文中加载。 (HRESULT 异常:0x80131058)
当我在 博客中搜索此错误的修复程序时,他们说要从 csproj 文件中删除与 targetframework 相关的标签,这应该有效,但这会导致构建错误,指出未找到 targetframework。
这就是我卡住的地方。我还附上了我未修改的 csproj 文件以供参考。
请注意,我已经在 Azure 中创建了一个基本的回声机器人,然后下载了这个基本的机器人,并根据我的要求在这个基本的机器人之上从头开始构建我自己的水对话。
请帮我解决这个问题,因为我尝试了一些没有用的东西。如果无法实现,请告诉我,以便我可以将其传达给我的团队。在此先感谢您的帮助。
我还尝试使用从 博客中获取的以下代码,但这也没有用。由于我被阻止了,我发布此查询以寻求帮助:
static void Main(string[] args)
{
CreateWorkItem();
}
public static void CreateWorkItem()
{
string _tokenAccess = "************"; //Click in security and get Token and give full access https://azure.microsoft.com/en-us/services/devops/
string type = "Bug";
string organization = "type your organization";
string proyect = "type your proyect";
string _UrlServiceCreate = $"https://dev.azure.com/{organization}/{proyect}/_apis/wit/workitems/${type}?api-version=5.0";
dynamic WorkItem = new List<dynamic>() {
new
{
op = "add",
path = "/fields/System.Title",
value = "Sample Bug test"
}
};
var WorkItemValue = new StringContent(JsonConvert.SerializeObject(WorkItem), Encoding.UTF8, "application/json-patch+json");
var JsonResultWorkItemCreated = HttpPost(_UrlServiceCreate, _tokenAccess, WorkItemValue);
}
public static string HttpPost(string urlService, string token, StringContent postValue)
{
try
{
string request = string.Empty;
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", token))));
using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(new HttpMethod("POST"), urlService) { Content = postValue })
{
var httpResponseMessage = httpClient.SendAsync(httpRequestMessage).Result;
if (httpResponseMessage.IsSuccessStatusCode)
request = httpResponseMessage.Content.ReadAsStringAsync().Result;
}
}
return request;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
以下是csproj文件中的数据供参考:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Bot.Builder.AI.QnA" Version="4.6.0" />
<PackageReference Include="Microsoft.Bot.Builder.Dialogs" Version="4.6.0" />
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Version="4.6.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="System.Data.SqlClient" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Web.Extensions">
<HintPath>..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Web.Extensions.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="PostDeployScripts\IncludeSources.targets" Condition="Exists('PostDeployScripts\IncludeSources.targets')" />
<Import Project="..\PostDeployScripts\IncludeSources.targets" Condition="Exists('..\PostDeployScripts\IncludeSources.targets')" />
</Project>
我正在关闭此查询,因为我通过尝试 post 中的想法得到了这个想法。它奏效了。
正如我在尝试 2 代码中所解释的那样,将数据转换为
JavascriptSerializer 对象到一个名为 JSON 的字符串中,作为从行开始的给定代码:
JavaScriptSerializer serializer = new JavaScriptSerializer();
我没有这样做,而是使用上面给出的博客创建了一个 class;并获取带有变量的属性 as
OP
小路
值
public class WorkItemData
{
public string op { get; set; }
public string path { get; set; }
public string value { get; set; }
}
在我实际的机器人代码中创建了一个列表变量:
List<WorkItemData> wiarray= new List<WorkItemData>;
将数据添加到 class 和数组,如上面给出的博客 link 所示,最后使用下面的代码行将其转换为 Json 并存储到变量中:
字符串 wijsondata = JsonConvert.SerializeObject(wiarray);
并使用我原来的问题中给出的 try 2 代码块的剩余部分称为 post 方法,而不是 Json 变量,我传递了 wijsondata
Content = new StringContent(wijsondata , Encoding.UTF8,"application/json-patch+json")
它奏效了。
感谢博客中或本 post 或外部 post 提供的所有帮助和想法,对于可能给任何人造成的任何不便,我们深表歉意。
我使用 BOT Framework SDK V4 通过 C# 创建了网络频道聊天机器人。它有多个瀑布对话框,根据在主对话框中选择的选项执行一组操作。
在其中一个对话框中,我的要求是用户输入一些数据,然后使用它我应该在我的 AZURE DEvOps 项目中创建一个类型任务的工作项以用于跟踪目的。我能够成功地从用户那里获取数据,但是在 devops 中创建 WORK ITEM 时我遇到了问题。我已经从我这边尝试了一些事情,但如果通过创建单独的 C# 控制台应用程序来执行,它们就可以工作,但是如果我尝试通过安装相关的 NuGET 包或添加参考程序集来使用相同的代码,我会收到错误或警告。
尝试一:在BOTCode中使用TFS相关的nuget包:
如果我尝试通过安装与 TFS Extended 客户端相关的 Nuget 包来使用代码,那么在安装过程中它会显示兼容性警告和我的参考程序集部分有一个警告符号。虽然我还没有尝试在我的对话框 class 中执行这段代码,因为虽然它可能有效,但我不确定在发布到 AZURE 后它是否会导致问题。
现在来试试2 尝试 2:在 BOT 代码中使用 AZURE DEVOPS REST API:
我已经编写了用于调用 REST API 的代码,因为我在我的对话框中使用了以下代码 class:
string token = "toekn";
string type = "Task";
string organization = org
string project = "Project";
int workitemid = 0;
string url = $"https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/${type}?api-version=5.0";
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(new object[]{new
{
op = "add",
path = "/fields/System.Title",
value = "Testing Workitem creation through API"
},
new {
op = "add",
path = "/fields/System.Description",
value = "Model Request ID#" + requestid + " from: "+ name + " requested from ChatBot"
},
new {
op = "add",
path = "/fields/Priority",
value = 1
}
});
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", token))));
var method = new HttpMethod("POST");
var request = new HttpRequestMessage(method, url)
{
Content = new StringContent(json, Encoding.UTF8,
"application/json-patch+json")
};
var sendresult = client.SendAsync(request).Result;
var result = sendresult.Content.ReadAsStringAsync().Result;
Console.WriteLine("Completed!");
dynamic workitemdata = JsonConvert.DeserializeObject(result);
workitemid = workitemdata.id;
};
现在如果你在上面的代码中观察到有一个方法 -
JavaScriptSerializer 序列化程序 = new JavaScriptSerializer();
这需要一个名为 system.web.extensions.dll 的程序集引用才能使用 我已经通过浏览此 DLL 添加了此引用,即 使用 System.Web.Script.Serialization;
现在当我执行这个时,我得到如下异常: 捕获到异常: 无法加载文件或程序集 'System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'。不应为执行加载引用程序集。它们只能在仅反射加载器上下文中加载。 (HRESULT 异常:0x80131058)
当我在
这就是我卡住的地方。我还附上了我未修改的 csproj 文件以供参考。
请注意,我已经在 Azure 中创建了一个基本的回声机器人,然后下载了这个基本的机器人,并根据我的要求在这个基本的机器人之上从头开始构建我自己的水对话。
请帮我解决这个问题,因为我尝试了一些没有用的东西。如果无法实现,请告诉我,以便我可以将其传达给我的团队。在此先感谢您的帮助。
我还尝试使用从
static void Main(string[] args)
{
CreateWorkItem();
}
public static void CreateWorkItem()
{
string _tokenAccess = "************"; //Click in security and get Token and give full access https://azure.microsoft.com/en-us/services/devops/
string type = "Bug";
string organization = "type your organization";
string proyect = "type your proyect";
string _UrlServiceCreate = $"https://dev.azure.com/{organization}/{proyect}/_apis/wit/workitems/${type}?api-version=5.0";
dynamic WorkItem = new List<dynamic>() {
new
{
op = "add",
path = "/fields/System.Title",
value = "Sample Bug test"
}
};
var WorkItemValue = new StringContent(JsonConvert.SerializeObject(WorkItem), Encoding.UTF8, "application/json-patch+json");
var JsonResultWorkItemCreated = HttpPost(_UrlServiceCreate, _tokenAccess, WorkItemValue);
}
public static string HttpPost(string urlService, string token, StringContent postValue)
{
try
{
string request = string.Empty;
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", token))));
using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(new HttpMethod("POST"), urlService) { Content = postValue })
{
var httpResponseMessage = httpClient.SendAsync(httpRequestMessage).Result;
if (httpResponseMessage.IsSuccessStatusCode)
request = httpResponseMessage.Content.ReadAsStringAsync().Result;
}
}
return request;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
以下是csproj文件中的数据供参考:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Bot.Builder.AI.QnA" Version="4.6.0" />
<PackageReference Include="Microsoft.Bot.Builder.Dialogs" Version="4.6.0" />
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Version="4.6.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="System.Data.SqlClient" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Web.Extensions">
<HintPath>..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Web.Extensions.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="PostDeployScripts\IncludeSources.targets" Condition="Exists('PostDeployScripts\IncludeSources.targets')" />
<Import Project="..\PostDeployScripts\IncludeSources.targets" Condition="Exists('..\PostDeployScripts\IncludeSources.targets')" />
</Project>
我正在关闭此查询,因为我通过尝试 post 中的想法得到了这个想法。它奏效了。
正如我在尝试 2 代码中所解释的那样,将数据转换为 JavascriptSerializer 对象到一个名为 JSON 的字符串中,作为从行开始的给定代码:
JavaScriptSerializer serializer = new JavaScriptSerializer();
我没有这样做,而是使用上面给出的博客创建了一个 class;并获取带有变量的属性 as
OP 小路 值
public class WorkItemData
{
public string op { get; set; }
public string path { get; set; }
public string value { get; set; }
}
在我实际的机器人代码中创建了一个列表变量:
List<WorkItemData> wiarray= new List<WorkItemData>;
将数据添加到 class 和数组,如上面给出的博客 link 所示,最后使用下面的代码行将其转换为 Json 并存储到变量中:
字符串 wijsondata = JsonConvert.SerializeObject(wiarray);
并使用我原来的问题中给出的 try 2 代码块的剩余部分称为 post 方法,而不是 Json 变量,我传递了 wijsondata
Content = new StringContent(wijsondata , Encoding.UTF8,"application/json-patch+json")
它奏效了。
感谢博客中或本 post 或外部 post 提供的所有帮助和想法,对于可能给任何人造成的任何不便,我们深表歉意。