C# 中的 Azure 计费 API 用法

Azure Billing API usage in C#

我正在研究来自 GitHub

的计费示例代码

更改 app.config 和 运行 示例中的所有相关信息后,我收到 404 错误。

我正在生成令牌并检查 fiddler 上的 URL 给我状态代码 404。URL 如下:

https://management.azure.com/subscriptions/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/providers/Microsoft.Commerce/UsageAggregates?api-version=2015-06-01-preview&reportedStartTime=2016-12-01T00%3a00%3a00%2b00%3a00&reportedEndTime=2017-02-01T00%3a00%3a00%2b00%3a00

请帮帮我。 在代码下方找到: Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Net;
using System.IO;
using System.Linq.Expressions;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
using System.Configuration;

namespace ARMAPI_Test
{

class Program
{
   //This is a sample console application that shows you how to grab a token from AAD for the current user of the app, and then get usage data for the customer with that token.
   //The same caveat remains, that the current user of the app needs to be part of either the Owner, Reader or Contributor role for the requested AzureSubID.
    static void Main(string[] args)
    {
        //Get the AAD token to get authorized to make the call to the Usage API
        string token = GetOAuthTokenFromAAD();

        /*Setup API call to Usage API
         Callouts:
         * See the App.config file for all AppSettings key/value pairs
         * You can get a list of offer numbers from this URL: http://azure.microsoft.com/en-us/support/legal/offer-details/
         * See the Azure Usage API specification for more details on the query parameters for this API.
         * The Usage Service/API is currently in preview; please use 2016-05-01-preview for api-version
         * Please see the readme if you are having problems configuring or authenticating: https://github.com/Azure-Samples/billing-dotnet-usage-api

        */
        // Build up the HttpWebRequest
        string requestURL = String.Format("{0}/{1}/{2}/{3}",
                   ConfigurationManager.AppSettings["ARMBillingServiceURL"],
                   "subscriptions",
                   ConfigurationManager.AppSettings["SubscriptionID"],
                   "providers/Microsoft.Commerce/UsageAggregates?api-version=2015-06-01-preview&reportedStartTime=2015-03-01T00%3a00%3a00%2b00%3a00&reportedEndTime=2017-02-01T00%3a00%3a00%2b00%3a00&aggregationGranularity=Hourly&showDetails=true");
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestURL);

        // Add the OAuth Authorization header, and Content Type header
        request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);
        request.ContentType = "application/json";

        // Call the Usage API, dump the output to the console window
        try
        {
            // Call the REST endpoint
            Console.WriteLine("Calling Usage service...");
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Console.WriteLine(String.Format("Usage service response status: {0}", response.StatusDescription));
            Stream receiveStream = response.GetResponseStream();

            // Pipes the stream to a higher level stream reader with the required encoding format. 
            StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
            var usageResponse = readStream.ReadToEnd();
            Console.WriteLine("Usage stream received.  Press ENTER to continue with raw output.");
            Console.ReadLine();
            Console.WriteLine(usageResponse);
            Console.WriteLine("Raw output complete.  Press ENTER to continue with JSON output.");
            Console.ReadLine();

            // Convert the Stream to a strongly typed RateCardPayload object.  
            // You can also walk through this object to manipulate the individuals member objects. 
            UsagePayload payload = JsonConvert.DeserializeObject<UsagePayload>(usageResponse);
            Console.WriteLine(usageResponse.ToString());
            response.Close();
            readStream.Close();
            Console.WriteLine("JSON output complete.  Press ENTER to close.");
            Console.ReadLine();
        }
        catch (Exception e)
        {
            Console.WriteLine(String.Format("{0} \n\n{1}", e.Message, e.InnerException != null ? e.InnerException.Message : ""));
            Console.ReadLine();
        }
    }
    public static string GetOAuthTokenFromAAD()
    {
        var authenticationContext = new AuthenticationContext(String.Format("{0}/{1}",
                                                                ConfigurationManager.AppSettings["ADALServiceURL"],
                                                                ConfigurationManager.AppSettings["TenantDomain"]));

        //Ask the logged in user to authenticate, so that this client app can get a token on his behalf
        var result = authenticationContext.AcquireToken(String.Format("{0}/", ConfigurationManager.AppSettings["ARMBillingServiceURL"]),
                                                        ConfigurationManager.AppSettings["ClientID"],
                                                        new Uri(ConfigurationManager.AppSettings["ADALRedirectURL"]),
                                                        PromptBehavior.Always);

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

        return result.AccessToken;
    }

}
}

下面是app.config中的键:

<add key="ADALServiceURL" value="https://login.microsoftonline.com" />
<!-- Service root URL for Azure AD instance WITH NO TRAILING SLASH! -->
<add key="ADALRedirectURL" value="http://localhost/" />
<!-- Redirect URL for Azure AD to use which MUST MATCH YOUR AAD APP CONFIGURATION! -->
<add key="ARMBillingServiceURL" value="https://management.azure.com" />
<!-- Service root URL for ARM/Billing service WITH NO TRAILING SLASH!  -->
<add key="TenantDomain" value="xxxxxx.onmicrosoft.com" />
<!-- DNS name for your Azure AD tenant, ie: contoso.onmicrosoft.com -->
<add key="SubscriptionID" value="xxxxxxxxx" />
<!-- GUID of Azure Subscription that is trusting AAD tenant specified above -->
<add key="ClientId" value="xxxxxx" />
<!-- GUID for AAD application configured as Native Client App in AAD tenant specified above -->

检查您的订阅和客户端 ID 的值。 当我使用 tenantid 而不是 subscriptionid 时出现 404 错误。 所以你传递的值之一是不正确的,很难说是哪一个。 仅供参考,我刚刚经历了所有相同的事情。 github 样本现在一切正常。