0

I want to use the json values in my c# code. So I have written the code like below

public static void WriteToIEMService(string jsonValue)
    {
        string TimeFormatText = DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss");
        string strFileCreationDate = DateTime.Now.ToString("dd/MM/yyyy");
        string strFileName = ConfigurationManager.AppSettings["IEM_SERVICEFILE"].ToString();

        try
        {            
           using (StreamWriter sw = File.CreateText(ConfigurationManager.AppSettings["LogFileDirectory"].ToString() + strFileName + "_" + strFileCreationDate + ".txt"))
            {
                List<MasterServiceResponse> records = JsonConvert.DeserializeObject<List<MasterServiceResponse>>(jsonValue);

                sw.WriteLine("IEM Service started and send data to IEM below");

                foreach (MasterServiceResponse record in records)
               {
                   sw.WriteLine(record.SapId);
               }
            }
        }
        catch (Exception)
        {

            throw;
        }
    }

But I am getting error as

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[IPColoBilling_BKP.App_Code.MasterServiceResponse]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

Please help

EDIT

My json values is as below

{"SiteData":[{"SAPId":"I-UW-SRPR-ENB-I001","SiteRFEIDate":"03-11-2014","SiteRFSDate":"03-11-2014","ID_OD":"ID","ID_ODchangeDate":"04-11-2018","NoofRRHBase":"0","RRHBaseChangeEffectiveDate":"","No_Of_Tenancy":"3","TenancyChangeEffectiveDate":"03-11-2014","SiteStatus":"Active","SiteDropDate":""}]}

UPDATE

public class MasterServiceResponse
{
    public string SapId { get; set; }
    public string AcknowledgementID { get; set; }
    public string FlagResponse { get; set; }
    public string ResponseMessage { get; set; }
    public string GisStatus { get; set; }
    public string GisSendDate { get; set; }
    public string SiteRFEIDate { get; set; }
    public string SiteRFSDate { get; set; }
    public string SiteRRHDate { get; set; }
    public string NoofRRHBase { get; set; }
}
Nad
  • 4,605
  • 11
  • 71
  • 160

4 Answers4

3

Update: A stated by Panagiotis Kanavos, You are not creating Root object, so you have to restructure your models.

Don't know what your Model looks like, But this error message says your giving json object where it is expecting JSON array,

Below is the model you should be using

public class SiteData
{
    public string SAPId { get; set; }
    public string SiteRFEIDate { get; set; }
    public string SiteRFSDate { get; set; }
    public string ID_OD { get; set; }
    public string ID_ODchangeDate { get; set; }
    public string NoofRRHBase { get; set; }
    public string RRHBaseChangeEffectiveDate { get; set; }
    public string No_Of_Tenancy { get; set; }
    public string TenancyChangeEffectiveDate { get; set; }
    public string SiteStatus { get; set; }
    public string SiteDropDate { get; set; }
}

public class RootObject
{
    public List<SiteData> SiteData { get; set; }
}

You also have to change the deserializing code

E.g.

RootObject records = JsonConvert.DeserializeObject<RootObject>(jsonValue);

foreach (SiteData record in records.SiteData)
{
   sw.WriteLine(record.SapId);
}
Mihir Dave
  • 3,954
  • 1
  • 12
  • 28
  • I cannot create again the class `SiteData`. I have already class as `MasterServiceResponse`. – Nad Nov 30 '18 at 08:59
  • 1
    Okay, then can you please attach your existing model here? so we can figure out what's wrong? – Mihir Dave Nov 30 '18 at 09:00
  • I have updated my question, have a look.. if u need anything else.. let me know – Nad Nov 30 '18 at 09:01
  • 1
    @BNN you *haven't* created a root class though. The JSON file contains an *object* whose `SiteData` property contains multiple `MasterServiceResponse` objects – Panagiotis Kanavos Nov 30 '18 at 09:04
  • Yes it is the issue "SiteData" is an object which contains the array of objects, List expects an array of objects, so you have to update your models accordingly – Mihir Dave Nov 30 '18 at 09:05
  • ohh, so I need to create that too for using json values ?? – Nad Nov 30 '18 at 09:06
  • Yes, and going forward you can use http://json2csharp.com to get exact models for your JSON – Mihir Dave Nov 30 '18 at 09:07
  • is this fine ? `List records = JsonConvert.DeserializeObject>(jsonValue);` – Nad Nov 30 '18 at 09:15
  • No, you have to change deserializing logic too, check updated answer. – Mihir Dave Nov 30 '18 at 09:18
  • Remember that you're deserializing the *whole* json file, not parts of it, every bit counts. – Lasse V. Karlsen Nov 30 '18 at 09:18
  • @MihirDave: `RootObject.SiteData` getting error as object reference is required in foreach – Nad Nov 30 '18 at 09:20
  • @MihirDave: now at foreach getting error as `Cannot convert type 'IPColoBilling_BKP.App_Code.SiteData' to 'IPColoBilling_BKP.App_Code.MasterServiceResponse'` – Nad Nov 30 '18 at 09:24
  • even I thought it should be like this `foreach (SiteData record in records.SiteData)` – Nad Nov 30 '18 at 09:26
  • yes mate, it worked perfectly fine now.. but whywas the `SiteData` giving issue – Nad Nov 30 '18 at 09:28
  • Good to Know, because I was saying records.SiteData is of type MasterServiceResponse which was wrong. and can you please accept the answer? – Mihir Dave Nov 30 '18 at 09:31
0

As the error mentions, you cannot deserialize JSON object to list. So instead of:

List<MasterServiceResponse> records = JsonConvert.DeserializeObject<List<MasterServiceResponse>>(jsonValue);

You should update have something like:

MyObject obj = JsonConvert.DeserializeObject<MyObject>(jsonValue);
Svetoslav Petrov
  • 1,036
  • 1
  • 11
  • 33
0

The exception message tells you that the JSON string contains single object, but you're tried to deserialize it into List<MasterServiceResponse> collection.

You should create a class to hold List<MasterServiceResponse>:

public class SiteData
{
    public List<MasterServiceResponse> MasterServiceResponse { get; set; }
}

Then you should replace this line:

List<MasterServiceResponse> records = JsonConvert.DeserializeObject<List<MasterServiceResponse>>(jsonValue);

to return single object like this:

SiteData records = JsonConvert.DeserializeObject<SiteData>(jsonValue);

Reference:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
  • if I use this, I am unable to use `foreach (MasterServiceResponse record in records) { sw.WriteLine(record.SapId); }` and getting error – Nad Nov 30 '18 at 09:03
0

Because your JSON start with a key "SiteData" which has an array value, you need to create a helper class to match that structure (e.g. class SiteResponse) with a property named SiteData of type List<MasterServiceResponse>.

Code:

public class SiteResponse
{
    public List<MasterServiceResponse> SiteData { get; set; }
}

private static void TestJson()
{
    var jsonValue = "{\"SiteData\":[{\"SAPId\":\"I-UW-SRPR-ENB-I001\",\"SiteRFEIDate\":\"03-11-2014\",\"SiteRFSDate\":\"03-11-2014\",\"ID_OD\":\"ID\",\"ID_ODchangeDate\":\"04-11-2018\",\"NoofRRHBase\":\"0\",\"RRHBaseChangeEffectiveDate\":\"\",\"No_Of_Tenancy\":\"3\",\"TenancyChangeEffectiveDate\":\"03-11-2014\",\"SiteStatus\":\"Active\",\"SiteDropDate\":\"\"}]}";

    var siteResponse = JsonConvert.DeserializeObject<SiteResponse>(jsonValue);
    List<MasterServiceResponse> records = siteResponse.SiteData;
}

Working demo here:
https://dotnetfiddle.net/wzg8AK

Peter B
  • 22,460
  • 5
  • 32
  • 69