Home > OS >  How do I deserialize a json list string to a list of object strings?
How do I deserialize a json list string to a list of object strings?

Time:12-19

I have a string object which I am trying to deserilize but when there is a json object in an another json object it has issues deserilizing.

[
  {
    "attributes": {
      "type": "Account",
      "url": "/services/data/77.0/object/Account/1234"
    },
    "Id": "1234",
    "IsDeleted": false,
    "MasterRecordId": null,
    "Name": "Stevens Smith",
    "LastName": null,
    "FirstName": null,
    "Salutation": null,
  },
  {
    "attributes": {
      "type": "Account",
      "url": "/services/data/v77.0/object/Account/12345"
    },
    "Id": "12345",
    "IsDeleted": false,
    "MasterRecordId": null,
    "Name": "Mr John Smith",
    "LastName": null,
    "FirstName": null,
    "Salutation": null,
  }
]

My Class is defined as follows:

    public Account() {
    public string? attributes;
    public string? id;
    public string? isDeleted;
    public string? masterRecordId;
    public string? name;
    public string? lastName;
    public string? firstName;
    public string? salutation;
}

The error message I get is Unexpected character encountered while parsing value: {. Path '[0].attributes', line 3, position 19.

CodePudding user response:

You should have two classes

public class Account() {
    public Attrubute attributes;
    public string? id;
    public string? isDeleted;
    public string? masterRecordId;
    public string? name;
    public string? lastName;
    public string? firstName;
    public string? salutation;
}

public class Attrubute() {
    public string? type;
    public string? url;
}

If you just want to save the Attrubute object as a string you could do something like this (syntax could be different depending if you're using newtonsoft or not)

public class Account() {
    public Attrubute attributes;
    public string? id;
    public string? isDeleted;
    public string? masterRecordId;
    public string? name;
    public string? lastName;
    public string? firstName;
    public string? salutation;
    public string attributesString => attributes != null ? JsonConvert.Serialize(attributes) : string.empty;
}

You want don't want to define the Attrubute class. You could make it dynamic object and if you want the string version - you could convert within your class. So something like this

public class Account {
    public string? id;
    public string? isDeleted;
    public string? masterRecordId;
    public string? name;
    public string? lastName;
    public string? firstName;
    public string? salutation;
    
    public dynamic attributes;
    public string Attributes => attributes != null ? JsonConvert.SerializeObject(attributes) : string.Empty;
}

CodePudding user response:

A lot of your variables are the wrong type. It's much safer to use the correct types - that way if you ever reserialize to JSON it will stay valid (for example isDeleted - even if you parse it in as a string, reserializing would store it as :"false" instead of :false).

public class Account
{
    public Attrubute attributes;
    public string stringAttributes //if you need a string accessor to attributes you can just use a property
        {
            get {
                return $"{attributes?.type}:{attributes?.url}";
            }
        }
    public string? id;
    public bool isDeleted;
    public string? masterRecordId;
    public string? name;
    public string? lastName;
    public string? firstName;
    public string? salutation;
}

public class Attrubute
{
    public string? type;
    public string? url;
}

If you do want to keep things as string, a better option is to leave it as json instead with JObject, and call .ToString() to return the json value when needed

public class Account
{
    public JObject attributes;
    public string? id;
    public JObject isDeleted;
    public string? masterRecordId;
    public string? name;
    public string? lastName;
    public string? firstName;
    public string? salutation;
    public string GetAttributesJson() {
         return attributes.ToString();
    }
}

CodePudding user response:

Your json string looks like a collection that holds 2 Account objects for example: Account[]

I had success deserializing this array using two different deserializers but because of the trailing comma after Salutation field the System.Json.Text deserializer needed an explicit option otherwise it throws.

Account[] accounts;

accounts = Newtonsoft.Json.JsonConvert.DeserializeObject<Account[]>(source)!;

// Need to remove trailing commas OR set option here.
accounts = System.Text.Json.JsonSerializer.Deserialize<Account[]>(
    source, 
    new JsonSerializerOptions { AllowTrailingCommas = true })!;

Where:

public class Account
{
    public Attributes? attributes { get; set; }
    public string? Id { get; set; }
    public bool IsDeleted { get; set; }
    public string? MasterRecordId { get; set; }
    public string? Name { get; set; }
    public string? LastName { get; set; }
    public string? FirstName { get; set; }
    public string? Salutation { get; set; }
}

public class Attributes
{
    public string type { get; set; }
    public string url { get; set; }
}

and:

const string source = @"
[
    {
    ""attributes"": {
        ""type"": ""Account"",
        ""url"": ""/services/data/77.0/object/Account/1234""
    },
    ""Id"": ""1234"",
    ""IsDeleted"": false,
    ""MasterRecordId"": null,
    ""Name"": ""Stevens Smith"",
    ""LastName"": null,
    ""FirstName"": null,
    ""Salutation"": null,
    },
    {
    ""attributes"": {
        ""type"": ""Account"",
        ""url"": ""/services/data/v77.0/object/Account/12345""
    },
    ""Id"": ""12345"",
    ""IsDeleted"": false,
    ""MasterRecordId"": null,
    ""Name"": ""Mr John Smith"",
    ""LastName"": null,
    ""FirstName"": null,
    ""Salutation"": null,
    }
]";
  • Related