Функция SDK библиотек управления Azure для .NET list() не работает для различных интерфейсов

Я использую библиотеки управления Azure (в частности, беглые) для создания веб-запроса к их API, чтобы получить список моих баз данных по моей подписке. Я могу получить экземпляр sqlserver с помощью Fluent, но не могу получить список всех баз данных на определенном сервере. Определить и удалить работу нормально, это просто функция list().

Я пытался использовать его для sqlserver.firewallrules, и функция списка там тоже не работает.

Вот некоторый код: журнал в какой-то момент просто приостанавливается, а затем пишет «вышел с кодом 0»

    public async Task<List<String>> getSqlDatabaseList()
    {
        System.Diagnostics.Debug.WriteLine("Starting to get database list");
        List<string> dbNameList = new List<string>();

        //the var azure is defined earlier in the project and is authenticated.
        var sqlServer = await azure.SqlServers.GetByResourceGroupAsync("<resource group name>", "<server Name>");

        //The code below successfully writes the server name
        System.Diagnostics.Debug.WriteLine(sqlServer.Name);

        //The code below here is where everyting stop and "has exited with code 0" happens after a few seconds of delay
        var dbList = sqlServer.Databases.List();

        //Never reaches this line
        System.Diagnostics.Debug.WriteLine("This line never is written");

        foreach (ISqlDatabase db in dbList)
        {
            dbNameList.Add(db.Name);
        }
        return dbNameList;
    }

Пояснение: я использую ASP.NET MVC Вот как мой метод контроллера получает доступ к методу класса. Resource Manager — это имя класса, который реализует getSQlDatabaseList();

        // GET: Home
    public async Task<ActionResult> Index()
    {
        ResourceManager rm = new ResourceManager();
        List<string> test = await rm.getSqlDatabaseList();
        //Never Gets to this line of code and never calls the for each or anything after
        foreach (var item in test)
        {
            System.Diagnostics.Debug.WriteLine(item);
        }
        System.Diagnostics.Debug.WriteLine("Is past for each");
        //AzureManager azm = await AzureManager.createAzureManager();
        //await azm.getResourceGroupList();
        return View(new UserLogin());
    }

person Andrew Taylor    schedule 19.05.2017    source источник
comment
Для большего пояснения: это часть веб-приложения, использующего Asp.net MVC.   -  person Andrew Taylor    schedule 20.05.2017


Ответы (1)


Согласно вашему коду и описанию, я предполагаю, что причина, по которой ваш код не смог создать таблицу, связана с вашим асинхронным getSqlDatabaseList.

Я предполагаю, что вы вызываете этот метод в основном методе консоли или как-то еще.

Если ваш основной метод выполняется полностью, ваш асинхронный метод getSqlDatabaseList не выполняется полностью и возвращает список строк. Это завершит все асинхронные методы.

Я предлагаю вам добавить ключевое слово await или result key при вызове метода getSqlDatabaseList, чтобы дождаться, когда поток полностью выполнит метод.

Более подробную информацию вы можете найти в тестовой демонстрации ниже.

  static void Main(string[] args)
        {
            //use result to wait the mehtod executed completely
            List<String> test =  getSqlDatabaseList().Result;

            foreach (var item in test)
            {
                Console.WriteLine(item);
            }

            Console.Read();

        }

        public static async Task<List<String>> getSqlDatabaseList()
        {
            //System.Diagnostics.Debug.WriteLine("Starting to get database list");
            List<string> dbNameList = new List<string>();

            var credentials = SdkContext.AzureCredentialsFactory.FromFile(@"D:\Auth.txt");

            var azure = Azure
                .Configure()
                .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
                .Authenticate(credentials)
                .WithDefaultSubscription();

            var sqlServer = await azure.SqlServers.GetByResourceGroupAsync("groupname", "brandotest");


            var dbList = sqlServer.Databases.List();

            foreach (ISqlDatabase db in dbList)
            {
                dbNameList.Add(db.Name);
            }
            return dbNameList;
        }

Обновлять:

Согласно вашему описанию, я создал тестовое приложение MVC. Как вы говорите, я воспроизвел вашу проблему.

Я думаю, что что-то не так с пакетом SDK для управления Azure.

Вот обходной путь, я предлагаю вам напрямую отправить rest API для получения базы данных.

Более подробную информацию вы можете найти в приведенных ниже кодах:

Отправьте запрос по адресу ниже:

https://management.azure.com/subscriptions/{subscriptionsid}/resourceGroups/{resourceGroupsname} /providers/Microsoft.Sql/servers/{servername}/databases?api-version={apiversion}

 public static List<String> getSqlDatabaseList()
        {
            //System.Diagnostics.Debug.WriteLine("Starting to get database list");
            List<string> dbNameList = new List<string>();

            string tenantId = "yourtenantid";
            string clientId = "yourclientId";
            string clientSecret = "clientSecret";
            string subscriptionid = "subscriptionid";
            string resourcegroup = "resourcegroupname";

            string sqlservername = "brandotest";
            string version = "2014-04-01";

            string authContextURL = "https://login.windows.net/" + tenantId;
            var authenticationContext = new AuthenticationContext(authContextURL);
            var credential = new ClientCredential(clientId, clientSecret);
            var result = authenticationContext.AcquireToken(resource: "https://management.azure.com/", clientCredential: credential);

            if (result == null)
            {
                throw new InvalidOperationException("Failed to obtain the JWT token");
            }

            string token = result.AccessToken;

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(string.Format("https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Sql/servers/{2}/databases?api-version={3}", subscriptionid, resourcegroup, sqlservername, version));

            request.Method = "GET";
            request.Headers["Authorization"] = "Bearer " + token;


            request.ContentType = "application/json";


            var httpResponse = (HttpWebResponse)request.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                string jsonResponse = streamReader.ReadToEnd();

                dynamic json = JsonConvert.DeserializeObject(jsonResponse);

                dynamic resultList = json.value.Children();


                foreach (var item in resultList)
                {

                    dbNameList.Add(((Newtonsoft.Json.Linq.JValue)item.name).Value.ToString());
                }
            }


            return dbNameList;
        }

Результат:

введите здесь описание изображения


Другой обходной путь.

Я предлагаю вам использовать thread.join, чтобы дождаться полного выполнения метода списка.

Код:

 public static async Task<List<String>> getSqlDatabaseList()
        {
            //System.Diagnostics.Debug.WriteLine("Starting to get database list");
            List<string> dbNameList = new List<string>();

            var credentials = SdkContext.AzureCredentialsFactory.FromFile(@"D:\Auth.txt");

            var azure = Azure
                .Configure()
                .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
                .Authenticate(credentials)
                .WithDefaultSubscription();

            var sqlServer = await azure.SqlServers.GetByResourceGroupAsync("brandosecondtest", "brandotest");

            IReadOnlyList<ISqlDatabase> dbList = null;

            Thread thread = new Thread(() => { dbList = sqlServer.Databases.List(); });
            thread.Start();
            //wait the thread
            thread.Join();

            foreach (ISqlDatabase db in dbList)
            {
                dbNameList.Add(db.Name);
            }
            return dbNameList;
        }

Результат:

введите здесь описание изображения

person Brando Zhang    schedule 22.05.2017
comment
Чтобы уточнить, это не консольное приложение, а веб-приложение, использующее MVC. Я пытался использовать ваш код, но код, кажется, зависает до получения sqlserver (мой завис при попытке получить список базы данных). - person Andrew Taylor; 22.05.2017
comment
Я загрузил свой ответ. - person Brando Zhang; 23.05.2017
comment
Спасибо. Вы случайно не знаете, когда будет выпущено обновление для SDK, чтобы решить эту проблему? - person Andrew Taylor; 23.05.2017
comment
Извините, я не знаю, когда решат этот вопрос. Но эта проблема связана с потоком. Вот еще один обходной путь, который вы можете использовать с плавным API. Смотрите мой ответ на обновление. - person Brando Zhang; 24.05.2017