PS: I have no prior C# knowledge.

I am currently attempting to Use SSIS to consume data from an API I found online (API link). I have attempted following steps found on this blog post (Dennis and Jim's Blog

However, I keep getting this error:

[Error getting data from Webservice!!] Error: System.MissingMethodException: No parameterless constructor defined for type of 'DrillDowns[]'. at System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject(IDictionary`2 dictionary, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject) at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject) at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit) at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input) at ScriptMain.GetWebServiceResult(String wUrl)

Here is a copy of the written code I've tried out:

public override void CreateNewOutputRows()
{
    //Get SSIS Variables

    //int population = this.Variables.MEASURE;

    //set Webservice URL
    string wUrl = "https://datausa.io/api/data?drilldowns=Nation&measures=Population";

    try
    {
        //call drilldowns to obtain Nation's population
        DrillDowns[] populationOutput = GetWebServiceResult(wUrl);

        //For each year output population
        foreach (var value in  populationOutput) 
        {
            Output0Buffer.AddRow();
            Output0Buffer.Population = value.Population;
            Output0Buffer.Year= value.Year;
            Output0Buffer.Nation = value.Nation;

        }
    }
    catch (Exception ex) 
    {
        FailComponent(ex.ToString());
    }
}
private DrillDowns[] GetWebServiceResult(string wUrl) 
{

    HttpWebRequest httpWReq= (HttpWebRequest)WebRequest.Create(wUrl);
    HttpWebResponse httpWResp = (HttpWebResponse)httpWReq.GetResponse();
    DrillDowns[] jsonResponse = null;

    try 
    {
        //Test the connection
        if (httpWResp.StatusCode == HttpStatusCode.OK) 
        {
            Stream responseStream= httpWResp.GetResponseStream();
            string jsonString = null;

            //Set jsonString using a stream reader
            using (StreamReader reader = new StreamReader(responseStream)) 
            {
                jsonString = reader.ReadToEnd().Replace("\\", "");
                reader.Close();
            }

            //Deserializing the Json
            JavaScriptSerializer sr = new JavaScriptSerializer();
            //JSON string comes with a leading and trailing " tthat needs to be removed for parsing to work correctly
            jsonResponse = sr.Deserialize<DrillDowns[]>(jsonString);

        
        }
        //Output connection error message
        else
        {
            FailComponent(httpWResp.StatusCode.ToString());
        }

    
    }
    //Output JSON parsing error
    catch (Exception ex) 
    {
        FailComponent(ex.ToString());
    }
    return jsonResponse;

}

private void FailComponent(string errorMsg) 
{
    bool fail = false;
    IDTSComponentMetaData100 compMetadata = this.ComponentMetaData;
    compMetadata.FireError(1, "Error getting data from Webservice!!", 
        errorMsg, "", 0, out fail);
}

//Class to hold our drillDowns
public class DrillDowns
{
    public string Nation { get; set; }

    public string Year { get; set; }

    public int Population { get; set; }

}

I'll be glad if I can be put through on what I'm missing.

1

There are 1 best solutions below

4
Raynoceros On

You need a parameterless constructor for DrillDowns to be able to let JavaScriptSerializer serialize

public class DrillDowns
{
    public string Nation { get; set; }

    public string Year { get; set; }

    public int Population { get; set; }

    public DrillDowns() { }
}