【问题标题】:How to call AZURE DEVOPS rest API in the water fall dialog built using C# BOT Framework SDK V4?如何在使用 C# BOT Framework SDK V4 构建的瀑布对话框中调用 AZURE DEVOPS REST API?
【发布时间】:2019-11-01 15:14:22
【问题描述】:

我有通过 C# 使用 BOT Framework SDK V4 创建的网络频道聊天机器人。它有多个瀑布对话框,根据在主对话框中选择的选项执行一组操作。

在其中一个对话框中,我的要求是用户输入一些数据,然后使用该数据在我的 AZURE DEvOps 项目中创建一个工作项类型任务以进行跟踪。我能够成功地从用户那里获取数据,但是在 devops 中创建 WORK ITEM 时我遇到了问题。我从我这边尝试了几件事,但如果通过创建单独的 C# 控制台应用程序执行它们,它们就可以工作,但是如果我尝试通过安装相关的 NuGET 包或添加参考程序集来使用相同的代码,我会收到错误或警告。

尝试1:在BOTCode中使用TFS相关的nuget包:

如果我尝试通过安装与 TFS 扩展客户端相关的 Nuget 包来使用代码,那么在安装期间它会显示兼容性警告,并且我的参考程序集部分有一个警告符号。通过我没有尝试在我的对话框类中执行这段代码,因为虽然它可能有工作但我不确定在发布到 AZURE 后它可能会导致问题。

现在来试试2 尝试 2:在 BOT 代码中使用 AZURE DEVOPS REST API:

我已经编写了调用 REST API 的代码,我在 Dialog 类中使用了以下代码:

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”。不应加载引用程序集以供执行。它们只能在 Reflection-only loader 上下文中加载。 (HRESULT 异常:0x80131058)

当我在 this 博客中搜索此错误的修复程序时,他们说要从 csproj 文件中删除与 targetframework 相关的标签,这应该可以工作,但这会产生构建错误,指出未找到 targetframework。

这是我卡住的地方。我还附上了我未修改的 csproj 文件以供参考。

请注意,我已经在 Azure 中创建了一个基本的回声机器人,然后下载了这个基本的机器人,并根据我的要求在这个基本的机器人之上从头开始构建我自己的水对话。

请帮助我解除阻止问题,因为我尝试了一些不起作用的方法。如果这无法实现,请让我知道,以便我可以与我的团队沟通。在此先感谢您的帮助。

我还尝试使用取自 this 博客的以下代码,这也不起作用。由于我被阻止,我发布此查询以寻求帮助:

 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>

【问题讨论】:

  • 首先,我认为这是您的问题中的拼写错误,而不是您的实际代码:string token = "toekn"; 其次,在您使用控制台应用程序的测试中,这也是 2.2 版 .NET Core 应用程序吗?出色地?您是否在该测试中使用 nuget 包?如果你能以这种方式重现,我认为你可以排除机器人框架。

标签: c# azure-devops botframework chatbot azure-devops-rest-api


【解决方案1】:

我正在关闭此查询,因为我通过尝试来自 post 的想法得到了这个想法。并且成功了。

正如我在 Try 2 代码中解释的将数据转换为 JavascriptSerializer 对象到一个称为 JSON 的字符串中,作为从该行开始的给定代码:

JavaScriptSerializer serializer = new JavaScriptSerializer();

我没有这样做,而是使用上面给出的博客创建了一个类;并获取变量为的属性

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>;

将数据添加到类和数组中,如上面给出的博客链接所示,然后最后使用下面的代码行将其转换为 Json 并存储到变量中:

字符串wijsondata = JsonConvert.SerializeObject(wiarray);

并使用我原来的问题中给出的 try 2 块的剩余部分代码,称为 post 方法,因为它现在而不是 Json 变量,我通过了 wijsondata

Content = new StringContent(wijsondata , Encoding.UTF8,"application/json-patch+json")

它奏效了。

感谢您在博客或本文或外部帖子中提供的所有帮助和想法,并对可能给任何人造成的任何不便表示歉意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多