Как использовать Task.Delay для вызова ответа GET после POSTing для внешнего API? - PullRequest
0 голосов
/ 05 ноября 2019

Я пытаюсь интегрировать использование внешнего API для выполнения вызовов POST и GET с моим клиентским приложением C # WPF. https://developers.virustotal.com/reference.

У меня есть следующие коды:

InfoProcessor.xaml.cs

        public static async Task<InfoModel> LoadInfo(string infoVar)
        {
            string apiKey = "xxxxxxxxxxxxx";
            //string resourceKey = "efbb7149e39e70c84fe72c6fe8cef5d379fe37e7238d19a8a4536fb2a3146aed"; 
            string resourceKey = infoVar;
            string url = $"https://www.virustotal.com/vtapi/v2/file/report?apikey={apiKey}&resource={resourceKey}";
            //await Task.Delay(30000);
            using (HttpResponseMessage response = await ApiStartup.ApiClient.GetAsync(url))
            {
                if (response.IsSuccessStatusCode)
                {
                    InfoModel info = await response.Content.ReadAsAsync<InfoModel>();

                    return info;
                }
                else
                {
                    throw new Exception(response.ReasonPhrase);
                }
            }
        }

        public static async Task<InfoModel> PostFileInfo(string filePath)
        {

            string url = "https://www.virustotal.com/vtapi/v2/file/scan";

            ApiStartup.ApiClient.DefaultRequestHeaders.Add("User-Agent", "VT API Service");

            using (var content = new MultipartFormDataContent())
            {
                var path = filePath;

                string assetName = Path.GetFileName(path);

                FileStream fs = File.OpenRead(path);

                var streamContent = new StreamContent(fs);
                streamContent.Headers.Add("Content-Type", "application/octet-stream");
                streamContent.Headers.Add("Content-Disposition", "form-data; name=\"file\"; filename=\"" + Path.GetFileName(path) + "\"");
                content.Add(streamContent, "file", Path.GetFileName(path));
                content.Add(CreateApiPart());

                //content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");


                Task<HttpResponseMessage> message = ApiStartup.ApiClient.PostAsync(url, content);

                InfoModel info = await message.Result.Content.ReadAsAsync<InfoModel>();
                return info;

            }



        }

ScanPage.xaml.cs

        string filePath;
        private void browseFileButton_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = false;
            openFileDialog.Filter = "All files (*.*)|*.*";
            openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            if (openFileDialog.ShowDialog() == true)
            {
                filePath = openFileDialog.FileName;
                fileLocation.Text = filePath;
            }
        }

private async void uploadFileButton_Click(object sender, RoutedEventArgs e)
        {
            if (filePath != null)
            {
                //await InfoProcessor.PostFileInfo(filePath, "https://www.virustotal.com/vtapi/v2/url/scan",);

                responseText.Text = "File queued for scanning, please wait a moment...";
                //var resultInfo = await InfoProcessor.PostInfo(filePath);
                var resultInfo = await InfoProcessor.PostFileInfo(filePath);
                await Task.Delay(60000);
                var resultInfo2 = await InfoProcessor.LoadInfo(resultInfo.Resource);
                //await Task.Delay(30000);
                responseText.Text = $"Scan Completed, MD5 checksum of file is {resultInfo2.Sha256} \n {resultInfo2.Positives} out of {resultInfo2.Total} {resultInfo2.Permalink} scan engines has detected to be potentially malicious";
            }
            else
            {
                MessageBox.Show("please upload a file");
            }
        }

После выбора и загрузки файла файл будет загружен и отсканирован с помощью функции PostFileInfo, содержимое ответа: resource id будет вставлено в функцию LoadInfo в качестве аргумента. ,

Когда файл сканируется, остальная часть содержимого ответа, например значения md5 / sha256 / sha1, которые должны были быть загружены, будет пустой до завершения сканирования, , что означает, что я будунеобходимо реализовать функцию Task.Delay между функциями PostFileInfo и LoadInfo.

Однако даже после задержки в 60 секунд между функциями результаты не отображаются в responseText.Text доя называю это второй раз через некоторое время. Правильно ли я реализую функцию Task.Delay?

Ответы [ 2 ]

0 голосов
/ 05 ноября 2019

В комментарии к вашему предыдущему вопросу я разместил ссылку на репозиторий с примером кода. Оттуда:

https://github.com/Genbox/VirusTotalNet/blob/master/src/VirusTotalNet.Examples/Program.cs

Program.cs, кажется, делает то, что вы пытаетесь сделать:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading.Tasks;
    using VirusTotalNet.Objects;
    using VirusTotalNet.ResponseCodes;
    using VirusTotalNet.Results;

    namespace VirusTotalNet.Examples
    {
        internal class Program
        {
            private static async Task Main(string[] args)
            {
                VirusTotal virusTotal = new VirusTotal("YOUR API KEY HERE");

                //Use HTTPS instead of HTTP
                virusTotal.UseTLS = true;

                //Create the EICAR test virus. See http://www.eicar.org/86-0-Intended-use.html
                byte[] eicar = Encoding.ASCII.GetBytes(@"X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*");

                //Check if the file has been scanned before.
                FileReport fileReport = await virusTotal.GetFileReportAsync(eicar);

                bool hasFileBeenScannedBefore = fileReport.ResponseCode == FileReportResponseCode.Present;

                Console.WriteLine("File has been scanned before: " + (hasFileBeenScannedBefore ? "Yes" : "No"));

                //If the file has been scanned before, the results are embedded inside the report.
                if (hasFileBeenScannedBefore)
                {
                    PrintScan(fileReport);
                }
                else
                {
                    ScanResult fileResult = await virusTotal.ScanFileAsync(eicar, "EICAR.txt");
                    PrintScan(fileResult);
                }

                Console.WriteLine();

                string scanUrl = "http://www.google.com/";

                UrlReport urlReport = await virusTotal.GetUrlReportAsync(scanUrl);

                bool hasUrlBeenScannedBefore = urlReport.ResponseCode == UrlReportResponseCode.Present;
                Console.WriteLine("URL has been scanned before: " + (hasUrlBeenScannedBefore ? "Yes" : "No"));

                //If the url has been scanned before, the results are embedded inside the report.
                if (hasUrlBeenScannedBefore)
                {
                    PrintScan(urlReport);
                }
                else
                {
                    UrlScanResult urlResult = await virusTotal.ScanUrlAsync(scanUrl);
                    PrintScan(urlResult);
                }
            }

            private static void PrintScan(UrlScanResult scanResult)
            {
                Console.WriteLine("Scan ID: " + scanResult.ScanId);
                Console.WriteLine("Message: " + scanResult.VerboseMsg);
                Console.WriteLine();
            }

            private static void PrintScan(ScanResult scanResult)
            {
                Console.WriteLine("Scan ID: " + scanResult.ScanId);
                Console.WriteLine("Message: " + scanResult.VerboseMsg);
                Console.WriteLine();
            }

            private static void PrintScan(FileReport fileReport)
            {
                Console.WriteLine("Scan ID: " + fileReport.ScanId);
                Console.WriteLine("Message: " + fileReport.VerboseMsg);

                if (fileReport.ResponseCode == FileReportResponseCode.Present)
                {
                    foreach (KeyValuePair<string, ScanEngine> scan in fileReport.Scans)
                    {
                        Console.WriteLine("{0,-25} Detected: {1}", scan.Key, scan.Value.Detected);
                    }
                }

                Console.WriteLine();
            }

            private static void PrintScan(UrlReport urlReport)
            {
                Console.WriteLine("Scan ID: " + urlReport.ScanId);
                Console.WriteLine("Message: " + urlReport.VerboseMsg);

                if (urlReport.ResponseCode == UrlReportResponseCode.Present)
                {
                    foreach (KeyValuePair<string, UrlScanEngine> scan in urlReport.Scans)
                    {
                        Console.WriteLine("{0,-25} Detected: {1}", scan.Key, scan.Value.Detected);
                    }
                }

                Console.WriteLine();
            }
        }
    }
0 голосов
/ 05 ноября 2019

Вместо того, чтобы делать задержку на количество секунд X, не могли бы вы написать некоторый код, чтобы проверить, есть ли значение в поле, в котором вы ищете значение, и затем продолжить только после того, как значение будет найдено там?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...