【问题标题】:Azure Management Libraries Sdk for .NET list() function not working for various interfacesAzure Management Libraries Sdk for .NET list() 功能不适用于各种接口
【发布时间】:2017-05-19 21:06:21
【问题描述】:

我正在使用 Azure 管理库(特别是 fluent)向他们的 api 创建 Web 请求,以获取我订阅下的数据库列表。我能够使用 fluent 获取 sqlserver 的实例,但无法获取特定服务器下所有数据库的列表。 定义和删除工作正常,它只是 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 这是我的控制器方法访问类方法的方式。资源管理器是实现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());
    }

【问题讨论】:

  • 更多说明:这是使用 Asp.net MVC 的 Web 应用程序的一部分。

标签: c# asp.net database asynchronous azure-sdk-.net


【解决方案1】:

根据您的代码和描述,我猜您的代码无法创建表的原因是您的异步​​ getSqlDatabaseList。

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

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

我建议你在调用getSqlDatabaseList方法的时候可以加上await或者result key关键字来等待线程完全执行该方法。

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

  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来获取数据库。

更多细节,您可以参考以下代码:

将请求发送到以下网址:

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 来等待 list 方法完全执行。

代码:

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

结果:

【讨论】:

  • 澄清这不是控制台应用程序,而是使用 MVC 的 Web 应用程序。我尝试使用您的代码,但在获取 sqlserver 之前代码似乎冻结了(我在尝试获取数据库列表时冻结了)。
  • 我已经上传了我的答案。
  • 谢谢。您是否偶然知道何时会对 sdk 进行更新以解决该问题?
  • 抱歉,不知道什么时候能解决这个问题。但是这个问题与线程有关。这是您可以使用流利的 api 的另一种解决方法。请参阅我的更新答案。
猜你喜欢
  • 1970-01-01
  • 2011-12-16
  • 1970-01-01
  • 2019-04-26
  • 2019-05-08
  • 2011-05-18
  • 2015-12-22
  • 1970-01-01
  • 2015-11-27
相关资源
最近更新 更多