Rodolphe Beck
Rodolphe Beck

Reputation: 363

Working with JSON from the AWS SDK Pricing API

I'm trying to work with AWS SDK in C# to follow and update a price catalog.

I'm using the method GetProductsAsync to list EC2 products for example, I then try to deserialize the response.

I use Json.Net to deserialize my response into a class I created using the "Paste JSON as classes" function from Visual Studio.

The object is somewhat populated, but the pricing model follows a weird JSON pattern.

Here is an extract of the object:

"terms":{
  "OnDemand":{
     "FBKCX9C4KX8NSVN3.JRTCKXETXF":{
        "priceDimensions":{
           "FBKCX9C4KX8NSVN3.JRTCKXETXF.6YS6EN2CT7":{
              "unit":"Hrs",
              "endRange":"Inf",
              "description":"$2.47 per On Demand RHEL m4.10xlarge Instance Hour",
              "appliesTo":[

              ],
              "rateCode":"FBKCX9C4KX8NSVN3.JRTCKXETXF.6YS6EN2CT7",
              "beginRange":"0",
              "pricePerUnit":{
                 "USD":"2.4700000000"
              }
           }
        },

The IDs under OnDemand and PriceDimensions seem to be references to other objects; therefore, they are not populated when I deserialize the JSON object, as they are different per product type.

Has anyone succeeded in getting pricing information for AWS assets?

Upvotes: 2

Views: 365

Answers (2)

Jose Macedo
Jose Macedo

Reputation: 308

AWS SDK have one more "level" after OnDemand.

I made my own class based on Brian Rogers answer, and i add the rest of the class to support Reserved and Products, making a nested class.

public class OuterObject
{
    public Dictionary<string, Products> products { get; set; }
    public Terms terms { get; set; }
}

public class Products
{
    public string sku { get; set; }
    public string productFamily { get; set; }
    public Attributes attributes { get; set; }
}

public class Attributes
{
    public string servicecode { get; set; }
    public string location { get; set; }
    public string locationType { get; set; }
    public string instanceType { get; set; }
    public string currentGeneration { get; set; }
    public string vcpu { get; set; }
    public string memory { get; set; }
    public string operatingSystem { get; set; }
    public string licenseModel { get; set; }
    public string preInstalledSw { get; set; }
    public string tenancy { get; set; }
}

public class Terms
{
    public Dictionary<string, Dictionary<string, OnDemandItem>> OnDemand { get; set; }
    public Dictionary<string, Dictionary<string, OnDemandItem>> Reserved { get; set; }
}


public class OnDemandItem
{
    public string offerTermCode { get; set; }
    public string sku { get; set; }
    public Dictionary<string, PriceDimensionsItem> priceDimensions { get; set; }
    public TermAttributes termAttributes { get; set; }
}

public class PriceDimensionsItem
{
    public string unit { get; set; }
    public string endRange { get; set; }
    public string description { get; set; }
    public object[] appliesTo { get; set; }
    public string rateCode { get; set; }
    public string beginRange { get; set; }
    public PricePerUnit pricePerUnit { get; set; }
}

public class PricePerUnit
{
    public string USD { get; set; }
}

public class TermAttributes
{
    public string LeaseContractLength { get; set; }
    public string OfferingClass { get; set; }
    public string PurchaseOption { get; set; }
}

Upvotes: 1

Brian Rogers
Brian Rogers

Reputation: 129797

For JSON objects having keys which can vary, you can use a Dictionary<string, T> in place of a regular class, where T is a class representing the item data. So in your case, you'd need a dictionary for both OnDemand and priceDimensions. The resulting class definitions would look like this:

public class OuterObject
{
    public Terms terms { get; set; }
}

public class Terms
{
    public Dictionary<string, OnDemandItem> OnDemand { get; set; }
}

public class OnDemandItem
{
    public Dictionary<string, PriceDimensionsItem> priceDimensions { get; set; }
}

public class PriceDimensionsItem
{
    public string unit { get; set; }
    public string endRange { get; set; }
    public string description { get; set; }
    public object[] appliesTo { get; set; }
    public string rateCode { get; set; }
    public string beginRange { get; set; }
    public PricePerUnit pricePerUnit { get; set; }
}

public class PricePerUnit
{
    public string USD { get; set; }
}

Demo: https://dotnetfiddle.net/dJ5jmQ

Note: you could also use a Dictionary<string, string> in place of the PricePerUnit class if you will be dealing with a lot of different currencies. If there will just one or two, then having a strongly-typed class with properties for each possible currency will work fine. For example, you could add a property public string EUR { get; set; } to handle Euro.

Upvotes: 3

Related Questions