Home > OS >  Delphi "Invalid class type case" issue
Delphi "Invalid class type case" issue

Time:08-11

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdBaseComponent,
  IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, DBXJSON, System.JSON;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    IdHTTP1: TIdHTTP;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
 const Url = 'url';


function JSONArrayCovertCnt(usJSON: string): integer;
var
  JSONPair : TJSONPair;
  JSONArray : TJSONArray;

begin
  usJson := StringReplace(usJSON,'\"','"',[rfReplaceAll]);
  JSONArray := TJSONObject.ParseJSONValue(usJSON) as TJSONArray;

  Result := JSONArray.Count;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  stream: TStringStream;                                                                                          idHttpObj: TIdHTTP;
  JSONValue : TJSONvalue;
  i : integer;
  JSONArray  : TJSONArray;
  result : integer;

begin
  stream := TStringStream.Create('', TEncoding.UTF8); //

  idHttpObj := TIdHTTP.Create(nil);
  idHttpObj.Get(Url, stream);
  idHttpObj.Free;

  JSONValue := TJSONObject.ParseJSONValue(stream.DataString);
  memo1.Clear;

  for i := 0 to 3 do
  begin
  Memo1.Lines.Add('year: '   JSONValue.GetValue<string>('data[' i.ToString '].year')   'year');
  Memo1.Lines.Add('hshld: '   JSONValue.GetValue<string>('data[' i.ToString '].hshld')   'hshld');
  Memo1.Lines.Add('popltn: '   JSONValue.GetValue<string>('data[' i.ToString '].popltn_sm')   '명');
  Memo1.Lines.Add('popltn_male: '   JSONValue.GetValue<string>('data[' i.ToString '].popltn_male')   '명');
  Memo1.Lines.Add('popltn_female: '   JSONValue.GetValue<string>('data[' i.ToString '].popltn_female')   '명');
  Memo1.Lines.Add('hshld_avrgpopltn: '   JSONValue.GetValue<string>('data[' i.ToString '].hshld_avrgpopltn')   '명');
  Memo1.Lines.Add('────────────────────────────────────');

  end;


  Memo1.Lines.Add('resultCode: '   JSONValue.GetValue<string>('resultCode'));
  Memo1.Lines.Add('resultMsg: '   JSONValue.GetValue<string>('resultMsg'));
  Memo1.Lines.Add('numOfRows : '   JSONValue.GetValue<string>('numOfRows'));
  Memo1.Lines.Add('resultCode: '   JSONValue.GetValue<string>('resultCode'));
  Memo1.Lines.Add('totalcount: '   JSONValue.GetValue<string>('totalCount'));

  result := JSONArrayCovertCnt(stream.DataString);
  edit1.Text := IntToStr(result);

  stream.Free;
end;

end.

JSON

{
"data":
    [
        {
        "popltn_female":134301,
        "year":"2012",
        "hshld_avrgpopltn":2.65,
        "hshld":102031,
        "popltn_sm":270460,
        "popltn_male":136159
        }
    ]

"pageNo":1,
"currentCount":9,
"resultCode":0,
"totalCount":9,
"numOfRows":10,
"resultMsg":"정상"
}

I want to calculate how many data array values are in a JSONValue.

I tried to find, input, and apply the function code through Google search, but I get an error.

Invalid class type cast

How can we solve this problem?

I asked a question using a translator because I am a Korean who is not good at English at all.

CodePudding user response:

The JSON data you have shown represents an object (which is denoted by { }), not an array (which is denoted by [ ]), so ParseJSONValue() will return a TJSONValue pointing at a TJSONObject, not a TJSONArray. As such, the as typecast to TJSONArray will fail with a runtime error. The data field inside the JSON object is an array.


On a side note, there are other problems with your code:

  • your use of StringReplace() is completely unnecessary and should be removed. Your JSON doesn't contain any '\' characters, but even if it did, removing anything from the JSON is wrong. You need to parse it exactly as it was received.

  • all of your Create/Free pairs need to be protected with try/finally.

  • you are leaking both TJSONValue objects that ParseJSONValue() returns.

  • you don't need the TStringStream at all, as TIdHTTP.Get()has an overload that returns a String.

  • Related