2

BACKGROUND

I need to generate the below JSON data:

JSON

{
  "Type": "ACCPAYCREDIT",
  "Status": "AUTHORISED",
  "Contact": { 
    "ContactID": "eaa28f49-6028-4b6e-bb12-d8f6278073fc" 
  },
  "Date": "2009-03-29",
  "LineAmountTypes": "Exclusive",
  "LineItems": [
    {
      "Description": "MacBook - White",
      "Quantity": 1.0000,
      "UnitAmount": 1995.00,
      "AccountCode": "720"
    }
  ]
}

So I've created the below Apex class

Apex Class

public class XeroCreditNote {

    public String Type;
    public String Status;
    public XeroContact Contact;
    public Date Date;  // <------- THIS LINE ERRORS
    public String LineAmountTypes;

    public LineItem[] LineItems;

    public class LineItem {

        public String Description;
        public Integer Quantity;
        public Decimal UnitAmount;
        public String AccountCode;

    }
}

But the line public Date Date; give me an error:

Identifier name is reserved: Date

The class is serialsied like this:

return (List<XeroCreditNote>) JSON.deserialize(jsonSerialized, List<XeroCreditNote>.class);

QUESTION

I would like to be able to set the Apex property name to something that isn't reserved but make sure the correct property name is used when the object is serialized.

How can I do this with Apex?

  • Can you also provide the code where you perform serialization into JSON? – Eduard Jul 18 '18 at 16:37
  • 2
    A solved problem in Java - @JsonProperty - but no such mechanism in Apex. – Keith C Jul 18 '18 at 16:47
  • @KeithC do you know if there is a Salesforce Idea for an addition like this to the Apex language? – Robs Jul 19 '18 at 11:39
  • 1
    @Robs I don't; if there isn't you could create one. Trouble is that only a few development oriented ideas get implemented a year and there are plenty of other development gaps already listed. – Keith C Jul 19 '18 at 12:24
4

If you want to use reserved keywords as keys in your JSON payload, the simplest solution is to just use Map<String, Object> rather than a concrete type.

system.debug(JSON.serialize(new Map<String, Object>{
    'Date' => Date.today()
}));

The only other alternative I know of is string replacement, which I would be leery of implementing, but should also be viable. I would be careful to search for "myKey": rather than just myKey when you do any such replacement.

3

The simplest approach for JSON output is the very hacky:

public class XeroCreditNote {
    ...
    public Date myVeryUniquePrefixDate;
    ..
}

and a replace of myVeryUniquePrefix with nothing in the JSON string.

  • That was going to be the second approach I recommended, but you already posted it so I'll omit. That said I think it's not the simplest. :) – Adrian Larson Jul 18 '18 at 16:51
  • 2
    @AdrianLarson With the concrete classes already present it would be... – Keith C Jul 18 '18 at 16:53
  • 2
    It's debatable either way. The OP has all options laid out in front of them now and can choose for themselves. – Adrian Larson Jul 18 '18 at 17:07
  • @AdrianLarson so the correct answer is both your approach and Keith C's approach, but I cannot mark both as correct. What should be done in this situation? If I create an answer from both your answers, it feels disingenuous, and most likely frowned upon, or is that OK? – Robs Jul 21 '18 at 19:03
  • @Robs Adrian is a moderator here so I'd go with his opinion. But can't resist adding my 2c... If they have both provided useful information certainly upvote both. If you applied one or other to solve your problem accept that one. If its a tie just pick whichever you like and add a comment to that effect. All the answers are kept for reference so people can see both answers. – Keith C Jul 21 '18 at 19:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.