You need to sign in to do that
Don't have an account?

Weird JSON Deserialize error
Hey all.
I'm working on a custom APEX REST service that will take a JSON payload delivered in the request body and deserialize it to a custom class type. This works just fine in my unit test, and when running from the developer console, but actually attempting the same type of request with the apigee app console results in the fairly cryptic error
"message": "Can not deserialize SObject out of VALUE_NUMBER_FLOAT token at [line:1, column:1]", "errorCode": "JSON_PARSER_ERROR"
Also, I have seen the error
"No such column 'reviewers' on sobject of type Challenge__c" show up.
The payload contains a single challenge__c object, an 4 lists of other object types. I am trying to deserialize the into this wrapper class so then I can insert the challenge, and then the lists of all the records related to it.
The line causing this error is
challengeService.challengePayload challengeData = (challengeService.challengePayload)JSON.deserialize(jsonBody, challengeService.challengePayload.class);
The defenition of the class is
global class challengePayload { public Challenge__c challenge; public list<Challenge_Comment_Notifier__c> notifiers = new list<Challenge_Comment_Notifier__c>(); public list<Challenge_Category__c> categories = new list<Challenge_Category__c>(); public list<Challenge_Prize__c> prizes = new list<Challenge_Prize__c>(); public list<Challenge_Reviewer__c> reviewers = new list<Challenge_Reviewer__c>(); }
Running this code works just fine, both in my unit test, and from the console.
string jsonBody = '{"reviewers":[{"attributes":{"type":"Challenge_Reviewer__c"},"Member_Reference__c":"testguy1"}],"prizes":[{"attributes":{"type":"Challenge_Prize__c"},"Place__c":1,"Points__c":1000,"Prize__c":"$1000.00","Value__c":1000.00},{"attributes":{"type":"Challenge_Prize__c"},"Place__c":2,"Points__c":500,"Prize__c":"$500.00","Value__c":500.00},{"attributes":{"type":"Challenge_Prize__c"},"Place__c":3,"Points__c":200,"Prize__c":"$200.00","Value__c":200.00}],"notifiers":[{"attributes":{"type":"Challenge_Comment_Notifier__c"},"Member_Reference__c":"testguy1"}],"challenge":{"attributes":{"type":"Challenge__c"},"Name":"test Challenge","End_Date__c":"2012-03-27T17:15:15.261+0000","Challenge_Id__c":"1231231232","Winner_Announced__c":"2012-04-03","Start_Date__c":"2012-03-20T17:15:15.262+0000","Description__c":"test Challenge","Requirements__c":"Test","Status__c":"hidden"},"categories":[{"attributes":{"type":"Challenge_Category__c"},"Category__c":"a04E00000017pWrIAI"}]}'; challengeService.challengePayload challengeData = (challengeService.challengePayload)JSON.deserialize(jsonBody, challengeService.challengePayload.class);
But running this
https://snap.apigee.com/GBvRyx
Not really sure what's going on, and why the erros seem to be flip flopping. I am wondering if perhaps apigee is not encoding the request properly or something? Below is my full class.
/************************************ Name: challengeService Author: Daniel Llewellyn (Kenji776) Date: 3/20/2012 Description: Creates a cloudspokes challenge and it's associated records when valid json data is passed to the post request. Data must include keys for challenge, and optionally may includes prizes, reviewers, categories, and people to notify on comment. *************************************/ @RestResource(urlMapping='/challengeService/v1/*') global class challengeService { @HttpPost global static string doPost(RestRequest req, RestResponse res) { string returnMessage = 'Operation pending'; try { //now we need to get at the body of the request, since that is going to contain all juicy data needed for creating the related records. string jsonBody = req.requestBody.toString(); //serialize the request body into a challenge data payload, which has the data for the challenge and all it's associated records. challengePayload challengeData = (challengePayload)JSON.deserialize(jsonBody, challengePayload.class); //insert the challenge itself. insert challengeData.challenge; //populate the notifiers with the challenge Id for(Challenge_Comment_Notifier__c ccn : challengeData.notifiers) { ccn.challenge__c = challengeData.challenge.id; } //insert the notifiers database.insert(challengeData.notifiers); //populate the categories with the challenge Id for(Challenge_Category__c cc : challengeData.categories) { cc.challenge__c = challengeData.challenge.id; } //insert the categories database.insert(challengeData.categories); //populate the prizes with the challenge Id for(Challenge_prize__c p : challengeData.prizes) { p.challenge__c = challengeData.challenge.id; } //insert the categories database.insert(challengeData.prizes); //populate the prizes with the challenge Id for(challenge_Reviewer__c r : challengeData.reviewers) { r.challenge__c = challengeData.challenge.id; } //insert the categories database.insert(challengeData.reviewers); returnMessage = challengeData.challenge.id; } catch(exception ex) { returnMessage = ex.getMessage() + ' Cause is ' + ex.getCause() + ' on line ' + ex.getLineNumber(); } return returnMessage; } global static list<sObject> populatLookup(list<sObject> objectsList) { map<string,id> lookupStringToMemberIdMap = new map<string,id>(); for(sObject obj : objectsList) { if(obj.get('Member_Reference__c') != null) { lookupStringToMemberIdMap.put((string) obj.get('Member_Reference__c'), null); } } list<Member__c> members = [select id, email__c, name from Member__c where name in : lookupStringToMemberIdMap.keySet() or email__c in : lookupStringToMemberIdMap.keySet()]; for(Member__c member : members) { lookupStringToMemberIdMap.put(member.email__c,member.id); lookupStringToMemberIdMap.put(member.name,member.id); } for(sObject obj : objectsList) { if(obj.get('Member_Reference__c') != null) { obj.put('member__c',lookupStringToMemberIdMap.get((string) obj.get('Member_Reference__c'))); obj.put('Member_Reference__c',null); } } return objectsList; } //custom class to handle the challenge and all it's associated data. global class challengePayload { public Challenge__c challenge; public list<Challenge_Comment_Notifier__c> notifiers = new list<Challenge_Comment_Notifier__c>(); public list<Challenge_Category__c> categories = new list<Challenge_Category__c>(); public list<Challenge_Prize__c> prizes = new list<Challenge_Prize__c>(); public list<Challenge_Reviewer__c> reviewers = new list<Challenge_Reviewer__c>(); } @isTest public static void testCreateChallenge() { //create the parent objects so our junction objects have something to reference later. Category__c cat1 = new Category__c(); cat1.name = 'test category 1'; insert cat1; Member__c member1 = new Member__c(); member1.name = 'testguy1'; member1.email__c = 'testguy1@testguyland.com'; member1.Profile_Pic__c = 'mypics.jpg'; insert member1; //validate json string deserialization into custom class string jsonBody = '{"reviewers":[{"attributes":{"type":"Challenge_Reviewer__c"},"Member_Reference__c":"testguy1"}],"prizes":[{"attributes":{"type":"Challenge_Prize__c"},"Place__c":1,"Points__c":1000,"Prize__c":"$1000.00","Value__c":1000.00},{"attributes":{"type":"Challenge_Prize__c"},"Place__c":2,"Points__c":500,"Prize__c":"$500.00","Value__c":500.00},{"attributes":{"type":"Challenge_Prize__c"},"Place__c":3,"Points__c":200,"Prize__c":"$200.00","Value__c":200.00}],"notifiers":[{"attributes":{"type":"Challenge_Comment_Notifier__c"},"Member_Reference__c":"testguy1"}],"challenge":{"attributes":{"type":"Challenge__c"},"Name":"test Challenge","End_Date__c":"2012-03-27T17:15:15.261+0000","Challenge_Id__c":"1231231232","Winner_Announced__c":"2012-04-03","Start_Date__c":"2012-03-20T17:15:15.262+0000","Description__c":"test Challenge","Requirements__c":"Test","Status__c":"hidden"},"categories":[{"attributes":{"type":"Challenge_Category__c"},"Category__c":"a04E00000017pWrIAI"}]}'; challengeService.challengePayload challengeData = (challengeService.challengePayload)JSON.deserialize(jsonBody, challengeService.challengePayload.class); //Create the challenge payload object. We will serialize it later and send it to the post method. challengePayload myPayload = new challengePayload(); myPayload.challenge = new challenge__c(); myPayload.challenge.Challenge_Id__c = '001231231232'; myPayload.challenge.Name = 'test Challenge'; myPayload.challenge.Description__c = 'test Challenge'; myPayload.challenge.End_Date__c = dateTime.now().addDays(7); myPayload.challenge.Requirements__c = 'Test'; myPayload.challenge.Start_Date__c = dateTime.now(); myPayload.challenge.Status__c = 'hidden'; myPayload.challenge.Winner_Announced__c = date.today().addDays(14); Challenge_Comment_Notifier__c notifier1 = new Challenge_Comment_Notifier__c(); notifier1.Member_Reference__c = member1.name; myPayload.notifiers.add(notifier1); Challenge_Category__c category1 = new Challenge_Category__c(); category1.category__c = cat1.id; myPayload.categories.add(category1); Challenge_Prize__c prize1 = new Challenge_Prize__c(); prize1.place__c = 1; prize1.points__c = 1000; prize1.prize__c = '$1000.00'; prize1.value__c = 1000.00; Challenge_Prize__c prize2 = new Challenge_Prize__c(); prize2.place__c = 2; prize2.points__c = 500; prize2.prize__c = '$500.00'; prize2.value__c = 500.00; Challenge_Prize__c prize3 = new Challenge_Prize__c(); prize3.place__c = 3; prize3.points__c = 200; prize3.prize__c = '$200.00'; prize3.value__c = 200.00; myPayload.prizes.add(prize1); myPayload.prizes.add(prize2); myPayload.prizes.add(prize3); Challenge_Reviewer__c reviewer1 = new Challenge_Reviewer__c(); reviewer1.Member_Reference__c = member1.name; myPayload.reviewers.add(reviewer1); //Serialize the object string jsonPayload = JSON.serialize(myPayload); System.debug('------------------- Serialized payload JSON format: ' + jsonPayload); //Create the rest request and send it with the json data. RestRequest req = new RestRequest(); RestResponse res = new RestResponse(); req.httpMethod = 'POST'; req.requestBody = blob.valueOf(jsonPayload); system.debug('---------------------- Request Bod'); system.debug(req.requestBody); string createChallenge = doPost(req,res); system.debug('------------------- Created Challenge. Result is: ' + createChallenge); //Get the challenge we just created, and it's related objects. list<Challenge__c> assertChallengeCreate = [select id, (select id, member__c from Challenge_Reviewers__r), (select id from Challenge_Categories__r), (select id from Challenge_Prizes__r), (select id, member__c from Challenge_Comment_Notifiers__r) from challenge__c where challenge_id__c = '001231231232']; //Verify the challenge got created system.assertEquals(1,assertChallengeCreate.size()); //Verify the categories got attached system.assertEquals(myPayload.categories.size(),assertChallengeCreate[0].Challenge_Categories__r.size()); //Verify the prizes got attached system.assertEquals(myPayload.prizes.size(),assertChallengeCreate[0].Challenge_Prizes__r.size()); //Verify the notifiers got attached system.assertEquals(myPayload.notifiers.size(),assertChallengeCreate[0].Challenge_Comment_Notifiers__r.size()); //Verfiy the reviewers got attached system.assertEquals(myPayload.reviewers.size(),assertChallengeCreate[0].Challenge_Reviewers__r.size()); //Verify the reviewer record got properly attached to it's member system.assertEquals(member1.id,assertChallengeCreate[0].Challenge_Reviewers__r[0].member__c); //Verify the comment notifier record got properly attached to it's member system.assertEquals(member1.id,assertChallengeCreate[0].Challenge_Comment_Notifiers__r[0].member__c); } }