Как вызвать AZURE DEVOPS rest API в диалоге падения воды, построенном с использованием C # BOT Framework SDK V4? - PullRequest
1 голос
/ 31 октября 2019

У меня есть чат-бот веб-канала, созданный через C # с использованием BOT Framework SDK V4. Он имеет несколько диалоговых окон с водопадом, которые выполняют набор действий на основе опции, выбранной в главном диалоговом окне.

В одном из диалогов мое требование заключается в том, чтобы пользователь вводил некоторые данные, а затем, используя это, я должен создать задачу «Рабочий элемент типа»в моем проекте AZURE DEvOps для целей отслеживания. Я успешно могу получить данные от пользователя, но при создании рабочего элемента в devops я сталкиваюсь с проблемой. Я попробовал несколько вещей со своей стороны, но они работают, если они выполняются путем создания отдельных консольных приложений C #, но если я пытаюсь использовать тот же код, устанавливая соответствующие пакеты NuGET или добавляя эталонные сборки, я получаю ошибки или предупреждения.

Попробуйте 1: Использование связанных с TFS пакетов nuget в BOTCode:

Если я попытаюсь использовать код, установив пакеты Nuget, связанные с расширенным клиентом TFS, то во время установкион говорит, что предупреждения о совместимости и мои разделы справочных сборок имеют символ предупреждения. Из-за того, что я не пытался выполнить этот кусок кода в своем диалоговом классе, потому что, хотя он может работать, но я не уверен, что после публикации в AZURE это может вызвать проблемы.

Теперь, когда придете попробовать 2 Попробуйте 2: Использование REST API AZURE DEVOPS в BOT Code:

Я написал код для вызова 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 serializer = new JavaScriptSerializer ();

ThisМне нужна ссылка на сборку: system.web.extensions.dll. Я добавил эту ссылку, просматривая эту DLL, т.е. используя System.Web.Script.Serialization;

Теперь, когда я выполняю это, я получаю исключение какниже: Обнаружено исключение: Не удалось загрузить файл или сборку 'System.Web.Extensions, Версия = 4.0.0.0, Культура = Нейтральный, PublicKeyToken = 31bf3856ad364e35'. Ссылочные сборки не должны загружаться для выполнения. Они могут быть загружены только в контексте загрузчика только для отражения. (Исключение из HRESULT: 0x80131058)

Когда я искал исправление этой ошибки в этом блоге, там сказали, что нужно удалить связанные с targetframework теги из файла csproj, и это должно работать, ноэто дало ошибки сборки, указывающие на то, что целевой фреймворк не найден.

Вот где я застрял. Я также прилагаю свой немодифицированный файл 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>

1 Ответ

2 голосов
/ 01 ноября 2019

Я закрываю этот запрос, поскольку получил идею, попробовав идею из поста . и это сработало.

Так как я объяснял в своем коде 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 и сохраняется в переменную:

string wijsondata = JsonConvert.SerializeObject (wiarray);

И с использованиемоставшаяся часть кода, приведенная в блоке try 2, указанном в моем исходном вопросе, называется методом post, поскольку теперь вместо переменной Json я передал wijsondata

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

И это сработало.

Спасибо за помощь и идеи, представленные в блоге или в этом посте или за его пределами, и приносим извинения за неудобства, которые это могло вызватьлюбой.

...