0

I have a ASP.NET method that needs to pull up some currency rates.

protected void btnTest_Click(object sender, EventArgs e)
{
    HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(string.Format("https://api.fixer.io/latest?base=JPY&symbols=SGD"));

    WebReq.Method = "GET";

    HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();

    string jsonString;
    using (Stream stream = WebResp.GetResponseStream())   
    {
        StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8);
        jsonString = reader.ReadToEnd();
    }

    JavaScriptSerializer js = new JavaScriptSerializer();
    Item[] rates = js.Deserialize<Item[]>(jsonString);

    for (int i = 0; i < rates.Length; i++)
    {
        Item rate = new Item();
        rate = (Item) (rates[i]);
        Rates rb=(Rates) rate.r;

        lblResult.Text = lblResult.Text + rb.SGD;
    }
}

This is the Item.cs class

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace ClientConsultationSystem
{
    public class Rates
    {
        public double SGD { get; set; }
    }

    public class Item
    {
        public string b { get; set; }
        public string d { get; set; }
        public Rates r { get; set; }
    }


}

Not sure what i am doing wrong, but i got this error.

No parameterless constructor defined for type of 'ClientConsultationSystem.Item[]'.

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
CanP
  • 11
  • Exactly what the error says. You need to define a parameterless constructor for `Item`. – Evan Trimboli Mar 06 '18 at 04:41
  • @EvanTrimboli ??? have you ever tried to define another constructor for an array? – Alexei Levenkov Mar 06 '18 at 04:43
  • Could you please clarify what type `JavaScriptSerializer` is? Code you have should work fine (as described in the post you copied it from - https://stackoverflow.com/questions/9586585/convert-json-to-a-c-sharp-array). Please [edit] post with that information (and in general remove unrelated code - just JSON as string constant should be enough - [MCVE]) – Alexei Levenkov Mar 06 '18 at 04:50
  • 1
    Please note that Microsoft states in the documentation for [JavaScriptSerializer](https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer(v=vs.110).aspx) that [Json.Net](https://www.newtonsoft.com/json) should be used instead. – crashmstr Mar 06 '18 at 17:48

3 Answers3

0

What Evan said. In other words.. your code needs constructors like:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace ClientConsultationSystem
{
    public class Rates
    {
        public Rates() { }  // optional constructor
        public Double SGD { get; set; }
    }

    public class Item
    {
        public Item()
        {
            r = new Rates();
        }
        public String b { get; set; }
        public string d { get; set; }
        public Rates r { get; set; }
    }
}
Adam Cox
  • 3,341
  • 1
  • 36
  • 46
  • Could you please explain why `public Rates() { }` would make *any* difference? – Alexei Levenkov Mar 06 '18 at 17:37
  • I've updated my answer with a comment in the code on `Item` constructor. Any time you construct a type, you will require a constructor. They cannot be inferred. Rather, they must be explicitly defined. – Adam Cox Mar 06 '18 at 17:41
  • Where did you read that? Some link could help (also obviously you can just try it yourself to find out that if you don't specify constructor default on is automatically provided)... – Alexei Levenkov Mar 06 '18 at 17:58
  • oops!. you are correct. i must be doing explicit constructor definitions out of habit now. Answer updated.. – Adam Cox Mar 06 '18 at 18:15
  • BTW.. FWIW... I have seen that error coming up when DI is not configured correctly. – Adam Cox Mar 06 '18 at 18:23
  • Because when you use DI in 99% cases your class has constructor with parameters (otherwise why would you use DI :) ) and it turns off creation of automatic default constructor. As result when some dependencies are not found DI frameworks would try default constructor and will fail as you don't add one and there is no default automatic one. – Alexei Levenkov Mar 06 '18 at 21:53
0

You need to convert into a List instead of an Item[] because JavascriptSerializer deserializes into an IEnumerable.

I made some changes to your code:

    JavaScriptSerializer js = new JavaScriptSerializer();
    var rates = js.Deserialize<List<Item>>(jsonString);

    for (int i = 0; i < rates.Count; i++)
    {
        Item rate = new Item();
        rate = (Item)(rates[i]);
        Rates rb = (Rates)rate.rates;
    }
    public class Item
    {

        public string @base { get; set; }
        public string date { get; set; }
        public Rates rates { get; set; }
    }

While deserializing it is important to have the object closely match the source. The @base is needed since base is a reserved word.

sammy
  • 524
  • 4
  • 11
0

Thank you so much for the responses. I managed to get it working. It's been a while since i starting programming the whole Intranet system for my company, so i am just relying on whatever knowledge i have from Java and what i did for my final year project to do programming.

protected void Page_Load(object sender, EventArgs e)
{
        HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(string.Format("https://api.fixer.io/latest?base=JPY&symbols=SGD"));
        WebReq.Method = "GET";

        HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();

        string json;
        using (Stream stream = WebResp.GetResponseStream())
        {
            StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8);
            json = reader.ReadToEnd();
        }

        var rates = JsonConvert.DeserializeObject<Item>(json);

        Item r = new Item();
        r = (Item)(rates);
        Rates rb = (Rates)r.rates;
        lblResult.Text = lblResult.Text + "" + rb.SGD;

    }

The Item class

public class Rates
{
        public double SGD { get; set; }
}

public class Item
{
    public Item()
    {
        rates = new Rates();
    }
    public string @base { get; set; }
    public string date { get; set; }
    public Rates rates { get; set; }
}

If there is any resources/books that can help me to build up my knowledge on JSON on C#, i would appreciate some sharing.

Once again, thank you very much from the bottom of my heart.

CanP
  • 11