Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I've been working quite a bit with @RemoteAction methods and have noticed there seem to be a few inconsistencies between what's allowed in the apex JSON.(de)serialize methods and what the automatic serialization/deserialization performed by @RemoteAction methods does.

Is there any authoritative list of what the different capabilities and limitations are of each? If not, what differences have you found?

As an example JSON.deserialize will not allow a type that contains a member of type object, while @RemoteAction parameters will deserialize any type of primitive that JSON supports into the object property.

share|improve this question

2 Answers 2

up vote 13 down vote accepted

I've experienced a couple gotchas and differences:

  1. DateTimes de/serialize as quoted strings:

    String christmasLunch = '2013-12-25T12:30:59.500Z'; //looks reasonable, runs ok too
    Json.deserialize(christmas, DateTime.class); //2013-01-01 00:00:00 - no month! no day!
    
    String independenceDay = '"2014-07-04T09:00:00.00Z"'; //carefully note double quotes
    Json.deserialize(independenceDay, DateTime.class); //2014-07-04 09:00:00 - better
    
  2. The serializer used by REST services can return nested result sets, for example:

    //SELECT Id, Name (SELECT Id, Name FROM Contacts) FROM Account
    [{
        "Id": "001000000000000AAA",
        "Name": "Test Account",
        "Contacts": [{
            "Id: "003000000000000AAA"
            "Name": "Test Contact"
        }
    }]
    

    For a time, the @RemoteAction serializer did not. (Until v28.0 - this is now documented).

  3. Whacky types may be serializable, but rightly throw a System.JSONException on deserialize:

    • Type Type unsupported in JSON: common.apex.runtime.bytecode.BytecodeSObjectType

    • DescribeSObjectResult No suitable constructor found for type

  4. @RemoteAction methods can serialize, but not deserialize ENUM values

    //apex:
    public enum SEASON {WINTER, SPRING, SUMMER, AUTUMN}
    @RemoteAction static public void parseSeason(SEASON which) {}
    
    //javascript:
    RemoteController.parseSeason('WINTER', function() {})
    //Exception: Unable to convert parameter to Apex type: expected SEASON, got String
    
  5. SObject DateTime must be transmitted Long unix timestamp format:

    //apex:
    @RemoteAction static public void parseUser(User me) {}
    
    //javascript:
    RemoteController.parseUser({CreatedDate: 1234567890000}, function() {})
    //this works fine
    
  6. but Apex DateTime must be transmitted in a different UTC String format:

    //apex
    @RemoteAction static public void parseDateTime(DateTime now) {}
    
    //javascript:
    RemoteController.parseDateTime(1234567890000, function() {})
    //Exception: Unable to convert date '1234567890000' to Apex type Datetime.
    
  7. watch out for crazy getter/setter action. Like SoapClient class mappings in PHP, they're not called!

share|improve this answer
1  
re: apex vs sObject date formats: twitter.com/dkador/status/378275074370846720 –  ca_peterson Jan 15 at 23:26
    
Also Enum's cannot be de-serialised with JS Remoting. –  Andrew Fawcett Jan 20 at 3:23

In addition to JSON.deserialize not supporting types with object properties I've found:

  • Returning from a @RemoteAction doesn't run getters, JSON.serialize does
  • JSON.deserialize and @RemoteAction deserialization both run setters (as you'd expect)
  • JSON.deserialize will not handle deserializing into List<Object>, @RemoteAction deserialization will deserialize primitives properly into List<Object> but complex types will deserialize as nulls.
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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