Azure 管理库 Sdk for .NET list() 函数不适用于各种接口

Azure Management Libraries Sdk for .NET list() function not working for various interfaces

我正在使用 Azure 管理库(特别是流利的)向他们的 api 创建 Web 请求,以获取我订阅的数据库列表。我能够使用流利的方式获取 sqlserver 的实例,但无法获取特定服务器下所有数据库的列表。 定义和删除工作正常,它只是 list() 函数。

我已经尝试将它用于 sqlserver.firewallrules,但列表功能在那里也不起作用。

这是一些代码: 日志在某个时候只是暂停然后写入 "has exited with code 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 下面是我的控制器方法如何访问 class 方法。资源管理器是实现 getSQlDatabaseList() 的 class 的名称;

        // 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());
    }

根据您的代码和描述,我猜您的代码无法创建 table 的原因与您的 async getSqlDatabaseList 有关。

我猜你在控制台 main 方法或其他方法中调用了这个方法。

如果您的 main 方法被完全执行,您的异步方法 getSqlDatabaseList 不会完全执行 return 字符串列表。它将结束所有异步方法。

建议在调用getSqlDatabaseList方法的时候加上await或者result关键字,等待线程执行完方法

更多细节,您可以参考下面的测试演示。

  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 应用程序。正如你所说,我已经重现了你的问题。

我认为 Azure Management Fluent SDK 有问题。

这里有一个解决方法,我建议你可以直接发送 rest api 来获取数据库。

更多详情,您可以参考以下代码:

发送请求到下面url:

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

结果: