C# Azure Oauth 2.0授权流以及调用Azure REST API

C# Azure Oauth 2.0授权流以及调用Azure REST API

了解Oauth 2.0授权流

想要调微软REST API,第一步学会获取Access Token是必须的。
OAuth 2.0 授权流
C# Azure Oauth 2.0授权流以及调用Azure REST API_第1张图片
这里附上微软OAuth 2.0 authorization官方文档

授权调用API代码

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using JsonRawDataFilter = System.Func<System.Object, System.String>;

namespace AzureWebTest.Controllers
{
    public class HomeController : Controller
    {
        //private String ApiKey { get; set; }
        string AccessToken = "";
        string RefreshToken = "";
        public ActionResult Index()
        {
            return View();
        }

        //public ActionResult About()
        //{
        //    ViewBag.Message = "Your application description page.";

        //    return View();
        //}




       
        public ActionResult Contact(AuthResponse response)
        {
            AuthenticationParameters parm = new AuthenticationParameters();
            parm.ClientId = "Your Client ID";
            //parm.Code = response.Code;
            //parm.scope = "https%3a%2f%2fgraph.microsoft.com%2fUser.Read.All+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.Read.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fUser.Read+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadBasic.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.AccessAsUser.All";       //%20https%3a%2f%2fgraph.microsoft.com%2fuser_impersonation
            //parm.RedirectUri = "https://localhost:8000/Home/Contact";
            parm.GrantType = "client_credentials";
            parm.ClientSecret = "Your Secret";
            parm.tenant = response.tenant;
           
            var result = AcquireTokenWithOutUser(parm);
            //var AccessToken = GetAccessToken();
            ViewData["Message"] = result.AccessToken;  //result.AccessToken;
            //this.ApiKey = result.AccessToken;
            GetMyData(result.AccessToken, result.RefreshToken, null);

            ViewBag.Message = "Your contact page.";

            return View();
        }
        [HttpPost]
        public JsonResult AzureRedirect()
        {
            var authorizationRequest = $"https://login.microsoftonline.com/common/oauth2/v2.0/authorize?" +
            $"client_id=****" +
            $"&response_type=code" +
            $"&redirect_uri=https://localhost:8000/Home/About" +     //https://air-east-us-x.avepointonlineservices.com/collector/paygo/authcode
            $"&response_mode=query" +
            $"&scope=https%3a%2f%2fgraph.microsoft.com%2fUser.Read.All+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.Read.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fUser.Read+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadBasic.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.AccessAsUser.All" +     //%20https%3a%2f%2fmanagement.azure.com%2fuser_impersonation   https://management.azure.com/user_impersonation
            $"&state=12345";
            return Json(authorizationRequest);
        }

        [HttpPost]
        public JsonResult AzureRedirectWithoutUser()
        {
            var authorizationRequest = $"https://login.microsoftonline.com/common/adminconsent?" +
            $"client_id=**" +
            $"&redirect_uri=https://localhost:8000/Home/Contact" +
            $"&state=12345";
            return Json(authorizationRequest);
        }


        //[Route("collector/paygo/authcode")]
        public ActionResult About(AuthResponse response)
        {
            AuthenticationParameters parm = new AuthenticationParameters();
            parm.ClientId = "**";
            parm.Code = response.Code;
            parm.scope = "https%3a%2f%2fgraph.microsoft.com%2fUser.Read.All+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.Read.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fUser.Read+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadBasic.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.AccessAsUser.All";       //%20https%3a%2f%2fgraph.microsoft.com%2fuser_impersonation
            parm.RedirectUri = "https://localhost:8000/Home/About";     //"https://localhost:44383/Home/About";
            parm.GrantType = "authorization_code";
            parm.ClientSecret = "**";
            var result = AcquireToken(parm);
            //var AccessToken = GetAccessToken();
            ViewData["Message"] = result.AccessToken;  //result.AccessToken;
            //this.ApiKey = result.AccessToken;
            GetMyData(result.AccessToken, result.RefreshToken, null);


            ViewBag.Message = "Your application description page.";
            return View();
        }

        // Line breaks for legibility only

        //POST /{tenant}/oauth2/v2.0/token HTTP/1.1
        //Host: https://login.microsoftonline.com
        //Content-Type: application/x-www-form-urlencoded

        public AuthenticationResult AcquireToken(AuthenticationParameters parameters)
        {
            var result = new AuthenticationResult();
            var serviceRoot = "https://login.microsoftonline.com";

            var tokenRequest = $"{serviceRoot}/**/oauth2/v2.0/token";
            var postContent = new
            {
                client_id = parameters.ClientId,
                scope = "https%3a%2f%2fgraph.microsoft.com%2fUser.Read.All+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.Read.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.ReadWrite.All+https%3a%2f%2fgraph.microsoft.com%2fUser.Read+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadWrite+https%3a%2f%2fgraph.microsoft.com%2fUser.ReadBasic.All+https%3a%2f%2fgraph.microsoft.com%2fDirectory.AccessAsUser.All",
                code = System.Web.HttpUtility.UrlEncode(parameters.Code),
                grant_type = parameters.GrantType,
                redirect_uri = parameters.RedirectUri,
                client_secret = System.Web.HttpUtility.UrlEncode(parameters.ClientSecret),
            };
            //Send request
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Accept.TryParseAdd("application/json");
                var body = new StringContent(ConvertToFormData(postContent), System.Text.Encoding.UTF8);
                //body.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                body.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
                var responseMessage = httpClient.PostAsync(tokenRequest, body).Result;
                var content = responseMessage.Content.ReadAsStringAsync().Result;
                if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var accessToken = JsonConvert.DeserializeObject<AzureAccessToken>(content);
                    result.AccessToken = accessToken.Access_token;
                    result.RefreshToken = accessToken.Refresh_token;
                    result.AccessTokenType = accessToken.Token_type;
                    result.ExpiresOn = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).AddSeconds(accessToken.Expires_on);
                    //result = AcquireTokenByResfeshToken(result);
                    if (!String.IsNullOrEmpty(accessToken.Id_token))
                    {
                        //payload = GetByIdToken(accessToken.Id_token);
                    }
                }
                else
                {
                }
            }
            return result;
        }
        // Line breaks are for legibility only.

        //POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token HTTP/1.1
        //Host: login.microsoftonline.com
        //Content-Type: application/x-www-form-urlencoded

        public AuthenticationResult AcquireTokenWithOutUser(AuthenticationParameters parameters)
        {
            var result = new AuthenticationResult();
            var serviceRoot = "https://login.microsoftonline.com";

            var tokenRequest = $"{serviceRoot}/**/oauth2/v2.0/token";
            var postContent = new
            {
                client_id = parameters.ClientId,
                scope = "https%3a%2f%2fgraph.microsoft.com%2f.default",
                client_secret = System.Web.HttpUtility.UrlEncode(parameters.ClientSecret),
                grant_type = parameters.GrantType,
            };
            //Send request
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Accept.TryParseAdd("application/json");
                var body = new StringContent(ConvertToFormData(postContent), System.Text.Encoding.UTF8);
                //body.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                body.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
                var responseMessage = httpClient.PostAsync(tokenRequest, body).Result;
                var content = responseMessage.Content.ReadAsStringAsync().Result;
                if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var accessToken = JsonConvert.DeserializeObject<AzureAccessToken>(content);
                    result.AccessToken = accessToken.Access_token;
                    result.RefreshToken = accessToken.Refresh_token;
                    result.AccessTokenType = accessToken.Token_type;
                    result.ExpiresOn = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).AddSeconds(accessToken.Expires_on);
                    //result = AcquireTokenByResfeshToken(result);
                    if (!String.IsNullOrEmpty(accessToken.Id_token))
                    {
                        //payload = GetByIdToken(accessToken.Id_token);
                    }
                }
                else
                {
                }
            }
            return result;
        }


        public AuthenticationResult AcquireTokenByResfeshToken(AuthenticationResult parameters)
        {
            var result = new AuthenticationResult();
            var serviceRoot = "https://login.microsoftonline.com";

            var tokenRequest = $"{serviceRoot}/**/oauth2/v2.0/token";
            var postContent = new
            {
                client_id = "**",
                scope = "https%3a%2f%2fmanagement.azure.com%2fuser_impersonation",
                refresh_token = System.Web.HttpUtility.UrlEncode(parameters.RefreshToken),
                grant_type = "refresh_token",   //parameters.GrantType,
                client_secret = System.Web.HttpUtility.UrlEncode("**"),
            };
            //Send request
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Accept.TryParseAdd("application/json");
                var body = new StringContent(ConvertToFormData(postContent), System.Text.Encoding.UTF8);
                //body.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                body.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
                var responseMessage = httpClient.PostAsync(tokenRequest, body).Result;
                var content = responseMessage.Content.ReadAsStringAsync().Result;
                if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var accessToken = JsonConvert.DeserializeObject<AzureAccessToken>(content);
                    result.AccessToken = accessToken.Access_token;
                    result.RefreshToken = accessToken.Refresh_token;
                    result.AccessTokenType = accessToken.Token_type;
                    result.ExpiresOn = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).AddSeconds(accessToken.Expires_on);
                    if (!String.IsNullOrEmpty(accessToken.Id_token))
                    {
                        //payload = GetByIdToken(accessToken.Id_token);
                    }
                }
                else
                {
                }
            }
            return result;
        }

        public JsonResult GetMyData(string token, string refreshToken, JsonRawDataFilter filter)
        {
            AccessToken = token;
            RefreshToken = refreshToken;
            //JsonRawDataFilter filter;
            //token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImllX3FXQ1hoWHh0MXpJRXN1NGM3YWNRVkduNCIsImtpZCI6ImllX3FXQ1hoWHh0MXpJRXN1NGM3YWNRVkduNCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9mZTNhZjJjMS1lNzYyLTRiNjItYWQzYi1lM2YxZWQ1ZGQwYTAvIiwiaWF0IjoxNTY2NTI0MzUwLCJuYmYiOjE1NjY1MjQzNTAsImV4cCI6MTU2NjUyODI1MCwiYWNyIjoiMSIsImFpbyI6IjQyRmdZRmh5L0U1UlpvSXJROWk5ODdYcXZ5enVHci9rNkhDTnVLQTNkOXNqVzh1U2tFTUEiLCJhbXIiOlsid2lhIl0sImFwcGlkIjoiN2Y1OWE3NzMtMmVhZi00MjljLWEwNTktNTBmYzViYjI4YjQ0IiwiYXBwaWRhY3IiOiIyIiwiZmFtaWx5X25hbWUiOiJXYW5nIiwiZ2l2ZW5fbmFtZSI6IkJvYiIsImdyb3VwcyI6WyJjZDI4NjFlNy01ZTlkLTQ5OTMtOTNkZC00NWMwNDE4YzM2ZjkiLCJkYWZlZGVhNC1hOTI1LTQyYjItYTE0YS1mYzkzMTNmZWFmY2MiLCJkZDNmMjE5Yi1mNzhiLTRiNmItYmMwNy1mZmY5ZDQ3YzA5YTUiLCJiMzcyMzc2Yy1mNzJiLTQxZDctOTkyNy0wOWE2OGUwMjExNGYiLCIyNTgyN2JjNy05ZDc5LTQ0ZDAtODQxNy1jZDJhYWRmNzk2YWQiLCIxZjRkMTc1Mi1iZWZkLTQ3MmYtOGNiMS03Mjg3NGRlNDZhZjkiLCJmNjM0NWQxMy0yYWE2LTQ3MTItOTY2OS04NTg2NTlmYzQ2YTkiLCI0MmQ4YjZlNi1mZDdiLTRiZmUtYTJkYi0xY2VmNjcwMTVmNWIiLCI3YWE5MGQ2My05ZTRhLTQyY2EtOTRlZi0xMjY5ODI3OWFjMjEiLCJhOGZlMWE4Zi00MzljLTQxOTMtYTE0Zi05N2E5OGJjZDc2ZGQiLCIxYThlMDk1NC1hNDY2LTQ4OTYtYTllNC1hZjA5YTAwZDMxN2YiLCI2ZDczMjMyZi1kM2JhLTQyZTgtODM5MS0wYzU2OTNmOTc3NDQiLCIzNzE5ZjIxOC1mNzIzLTQ0MmMtOTA5MC04YjE4OWI3NGQxZTMiLCJhMDE1MjA3Ny02MGVkLTRkMzUtYTQ0Ni0wOGZlMjg1Y2E3OGYiLCJhMzAxNWFlYy02YjRkLTQ2MDctOTZmMC01ZGIyODMzODE4MzkiLCJjNjNlZjQ0NC1mYzYyLTQzMjQtODNiNC04ZTg0NWMxNDVlNWYiLCI0ODIwMWEwZS1mODM5LTQwYmYtOTViZi05YTI0MjY1NDQwYTEiLCIzZjNlMTk5Mi05NGU0LTRjZjQtYmNkZS0zMTZlN2NlYmI1ZDciLCIzOGE0ZmJiZC00YzYzLTQyMTAtYWZkMC1lMDgzYmQ4MTYxNjIiLCI1NjE1MjA1ZS0yZTRkLTQ2ODUtYmZiZi1kYWQ1ZjlkZDllMmUiLCI4ZmY4ODUwYi0zODU2LTRkYWItYjBmNC03OTEwMDM2OTllM2EiLCI0YTQ0Mjk1ZC0zMTk3LTQxMmYtOTdmNi1lM2RmZGYxNmE1Y2EiLCIxODY1OWJmNy00MjhiLTQ2ZTctODM4ZC03NmZmNTgyYjY5N2UiXSwiaXBhZGRyIjoiMTIzLjE3Ny4yMi4yNTEiLCJuYW1lIjoiQm9iIFdhbmciLCJvaWQiOiJkYTBkMGQ5YS1jOWEyLTQ5YzgtODAwOC1iYjg1Y2UzOGM1OGMiLCJvbnByZW1fc2lkIjoiUy0xLTUtMjEtNDI1MDQ3NTg3OC0zMzE4MzE0ODI0LTIxMTUxNTc1MTQtNDkzODIiLCJwdWlkIjoiMTAwMzIwMDA1MDFBQUU4OSIsInNjcCI6InVzZXJfaW1wZXJzb25hdGlvbiIsInN1YiI6IndhWGlTbGdYekVhZXZ3UWF5djFEZDgtMWhYb2lJUlhiNVhHcmFvVXhiZXMiLCJ0aWQiOiJmZTNhZjJjMS1lNzYyLTRiNjItYWQzYi1lM2YxZWQ1ZGQwYTAiLCJ1bmlxdWVfbmFtZSI6ImJvYi53YW5nQGF2ZXBvaW50LmNvbSIsInVwbiI6ImJvYi53YW5nQGF2ZXBvaW50LmNvbSIsInV0aSI6IkF6LUJUWm9CTWttV1d5cFJEaXBnQUEiLCJ2ZXIiOiIxLjAifQ.rS4PDQa4h43JNDhUB1i8C03S10F_lZWOAXD-TIMyl38t7pIUvVzO9GTsb7TcJAiQylsSxvhaaUQHWMBOA0NyTG-T4WR_ByWi-OvQxi5LFaPXEaSBvKF_dxmHDyuIIrgIiTHkxlxqGHVJeeV64tTY5fFnCOR8Bj0h4R6txwPp40uGhLZBfmKMpyOz0S9CpBfGnJB_x_xXpocAtcUf93njqLeKJjCge6us8_aGhFjbwxzqb_tBCBr99EYiRIdLSok3ZJMD4Oc9dn6D2sP88iKP2Vhc3pfJcEHjwaAyT9LPz5qyz9I3AXc6Mp22aCiZFx7wKlGJIv9zlbBhe8SNDCUzBg";

            //var requestUri = "https://graph.microsoft.com/v1.0/users";

            //var requestUri = "https://graph.microsoft.com/v1.0/me";

            var requestUri = "https://graph.microsoft.com/v1.0/users/**";

            //RawData result = null;
            UsageAggregateRawData result = null;
            var tempResult = new UsageAggregateRawData { Value = new List<UsageAggregate>() };
            //do
            //{
                using (var httpClient = new HttpClient { Timeout = TimeSpan.FromHours(1) })
                {

                    httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {AccessToken}");
                    httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
                    using (var httpResponseMessage = httpClient.GetAsync(requestUri).Result)
                    {
                        if (httpResponseMessage.StatusCode == HttpStatusCode.OK)
                        {

                            var resultValue = httpResponseMessage.Content.ReadAsStringAsync().Result;
                            //var jsonObject = JsonConvert.DeserializeObject<UsageAggregateRawData>(resultValue);
                            //jsonObject.Value.ForEach(data =>
                            //{
                            //    if (filter != null)
                            //        filter(data);
                            //    tempResult.Value.Add(data);
                            //});
                            //requestUri = jsonObject.NextLink;
                            //Thread.Sleep(600000);   //1000 * 60 * 10 = 10min
                        }
                        else
                        {
                            //var AuthResult = new AuthenticationResult();
                            //AuthenticationResult parameters = new AuthenticationResult();
                            //parameters.RefreshToken = refreshToken;
                            //AuthResult = AcquireTokenByResfeshToken(parameters);
                            //RefreshToken = AuthResult.RefreshToken;
                            //AccessToken = AuthResult.AccessToken;
                        }
                    }
                }
            //} while (requestUri != null && requestUri != "");


            return Json(null);
        }

        public class AuthResponse
        {
            public String Code { get; set; }

            public String Id_Token { get; set; }

            public String Error { get; set; }

            public String Error_Description { get; set; }

            public String Resource { get; set; }

            public String State { get; set; }

            public string session_state { get; set; }

            public string tenant { get; set; }
            public Boolean admin_consent { get; set; }

        }
        public class AuthenticationResult
        {
            public String AccessTokenType { get; set; }
            public String AccessToken { get; set; }
            public String RefreshToken { get; set; }
            public DateTimeOffset ExpiresOn { get; set; }
            public String TenantId { get; set; }
            public AzureUserInfo UserInfo { get; set; }
            public String IdToken { get; set; }
        }
        public class AzureUserInfo
        {
            /// <summary>
            ///  Gets identifier of the user authenticated during token acquisition.
            /// </summary>
            public String UniqueId { get; set; }
            public String UserPrincipalName { get; set; }
            public String GivenName { get; set; }
            public String FamilyName { get; set; }
        }
        public class AuthenticationParameters
        {
            public string scope { get; set; }
            public String GrantType { get; set; }
            public String ClientId { get; set; }
            public String ClientSecret { get; set; }
            public String Code { get; set; }
            public String RedirectUri { get; set; }
            /// <summary>
            /// Jwt token format
            /// </summary>
            public String IdToken { get; set; }

            public String RefreshToken { get; set; }
            public string tenant { get; set; }
            public Boolean admin_consent { get; set; }
        }
        private static String ConvertToFormData(Object data)
        {
            var bodyBuilder = new System.Text.StringBuilder();
            var objectType = data.GetType();
            Array.ForEach(objectType.GetProperties(),
                item => bodyBuilder.Append(item.Name).Append('=').Append(item.GetValue(data, null)).Append('&'));
            return bodyBuilder.ToString().Trim('&');
        }
        public class AzureAccessToken
        {
            public String Access_token { get; set; }
            public String Token_type { get; set; }
            /// <summary>
            /// How long the access token is valid (in seconds).
            /// </summary>
            public Int64 Expires_in { get; set; }
            /// <summary>
            /// The time when the access token expires.
            /// The date is represented as the number of seconds from 1970-01-01T0:0:0Z UTC until the expiration time.
            /// </summary>
            public Int64 Expires_on { get; set; }
            /// <summary>
            /// The App ID URI of the web API (secured resource).
            /// </summary>
            public String Resource { get; set; }

            public String Refresh_token { get; set; }
            /// <summary>
            /// An unsigned JSON Web Token (JWT).
            /// The app can base64Url decode the segments of this token to request information about the user who signed in.
            /// </summary>
            public String Id_token { get; set; }
        }


        public class UsageAggregateRawData : RawData
        {
            public List<UsageAggregate> Value { get; set; }

            public String NextLink { get; set; }
        }
        public class UsageAggregate
        {
            public String Id { get; set; }

            public String Name { get; set; }

            public String Type { get; set; }

            public Properties Properties { get; set; }
        }
        public class Properties
        {
            public String SubscriptionId { get; set; }
            public String UsageStartTime { get; set; }
            public String UsageEndTime { get; set; }
            public String MeterId { get; set; }
            public InfoFields InfoFields { get; set; }

            [JsonProperty("instanceData")]
            public String InstanceDataRaw { get; set; }

            public InstanceDataType InstanceData
            {
                get
                {
                    if (!String.IsNullOrEmpty(this.InstanceDataRaw))
                    {
                        return JsonConvert.DeserializeObject<InstanceDataType>(InstanceDataRaw.Replace("\\\"", ""));
                    }
                    return null;
                }
            }
            public Double Quantity { get; set; }
            public String Unit { get; set; }
            public String MeterName { get; set; }
            public String MeterCategory { get; set; }
            public String MeterSubCategory { get; set; }
            public String MeterRegion { get; set; }
        }
        public class RawData { }
        public class InfoFields
        {
            public String MeteredRegion { get; set; }
            public String MeteredService { get; set; }
            public String Project { get; set; }
            public String MeteredServiceType { get; set; }
            public String ServiceInfo1 { get; set; }
        }
        public class InstanceDataType
        {
            [JsonProperty("Microsoft.Resources")]
            public MicrosoftResources MicrosoftResources { get; set; }
        }
        public class MicrosoftResources
        {
            public String ResourceUri { get; set; }

            public IDictionary<String, String> Tags { get; set; }

            public IDictionary<String, String> AdditionalInfo { get; set; }

            public String Location { get; set; }

            public String PartNumber { get; set; }

            public String OrderNumber { get; set; }
        }

    }
}

更多请了解Rest API官方文档

仅供学习参考,如有侵权请联系我删除

你可能感兴趣的:(c#,azure,oauth,微软)