2

What am i doing wrong due to which i am getting JSON_PARSER_ERROR, I am using code below to parse json below :

@RestResource(urlMapping='/Imbellus/CandidateScore')
global with sharing class ImbellusScoreController {
    // workbench request URL : /services/apexrest/Imbellus/CandidateScore
    @HttpPost   
    global static String captureScores(String scoreJson) {
        System.debug('Score JSON: '+scoreJson);
        ScoresList scoreLst = (ScoresList)JSON.deserialize(scoreJson, ScoresList.class);
        System.debug('----scoreLst----' + scoreLst);
        return '';
    }
    public class ScoresList {
        public List<Score> scores;
    }
    public class score {
        public String Overall_Behavioral_Score_c;
        public String Overall_Drive_Achieving_Score_c;
        public String Overall_Functional_Screen_Score_c;
        public String Overall_Leadership_Score_c;
        public String Interview_Overall_Score_c;

    }
}

URL in workbench /services/apexrest/Imbellus/CandidateScore

json in request body

{
"scores":
[
{
"Overall_Behavioral_Score_c" : "50",
"Overall_Drive_Achieving_Score_c" : "60",
"Overall_Functional_Screen_Score_c" : "70",
"Overall_Leadership_Score_c" : "80",
"Interview_Overall_Score_c" : "90"
},
{
"Overall_Behavioral_Score_c" : "15",
"Overall_Drive_Achieving_Score_c" : "16",
"Overall_Functional_Screen_Score_c" : "17",
"Overall_Leadership_Score_c" : "18",
"Interview_Overall_Score_c" : "19"
}
]
}

[ { "message" : "Unexpected parameter encountered during deserialization: scores at [line:3, column:2]", "errorCode" : "JSON_PARSER_ERROR" } ]

  • 1
    Do you get any other details in the error message and if you can add those here? – Jayant Das Aug 3 '18 at 13:20
  • [{ "message" : "Unexpected parameter encountered during deserialization: scores at [line:3, column:2]", "errorCode" : "JSON_PARSER_ERROR" } ] – Walker Aug 3 '18 at 13:23
  • 2
    Are you sure that's the JSON string that you're being passed (have you checked your debug logs)? I tried to reproduce your issue by copy/pasting the inner classes into anonymous apex and calling JSON.deserialize(), but it's working fine for me. – Derek F Aug 3 '18 at 13:28
  • debug statement is not getting executed. workbench is throwing exception JSON_PARSER_ERROR. i am passing that json in question post in workbench request body. – Walker Aug 3 '18 at 13:30
  • I too was able to parse the JSON as in the post with the same code snippet successfully. – Jayant Das Aug 3 '18 at 13:45
6

The signature of the REST method is confusing Salesforce.

global static String captureScores(String scoreJson) {

should be

global static String captureScores(ScoresList inboundScoresList) {

With REST methods, Salesforce manages the deserialization for you based on an incoming JSON object whose keys map to the names of your parameters. Here, Salesforce is trying to deserialize your ScoresList JSON into an object containing a String whose key is scoresJson, which isn't working because it's a ScoresList that you yourself are hoping to deserialize. That's why you get an error "Unexpected parameter encountered" - Salesforce isn't expecting the parameter "scores", it's expecting "scoresJson", and the error's thrown before control hits your method and you attempt your own deserialization.

Changing the signature of the method and letting Salesforce do the deserialization should work.

Here's how to demonstrate this.

First, note that if you copy and paste the classes and the JSON into Anonymous Apex, you'll get no errors. Your code's correct if you assume that the incoming parameter is a string containing the JSON you show in your question.

But in Workbench, you get the JSON parser error when you send that JSON body.

If instead you embed your JSON string into an outer object with the key `"scoreJson", like this,

{"scoreJson" : "{\"scores\":[{\"Overall_Behavioral_Score_c\" : \"50\",\"Overall_Drive_Achieving_Score_c\" : \"60\",\"Overall_Functional_Screen_Score_c\" : \"70\",\"Overall_Leadership_Score_c\" : \"80\",\"Interview_Overall_Score_c\" : \"90\"},{\"Overall_Behavioral_Score_c\" : \"15\",\"Overall_Drive_Achieving_Score_c\" : \"16\",\"Overall_Functional_Screen_Score_c\" : \"17\",\"Overall_Leadership_Score_c\" : \"18\",\"Interview_Overall_Score_c\" : \"19\"}]}"}

it succeeds through Workbench REST Explorer with no code changes.

This is because Salesforce is able to deserialize this JSON blob to find a String parameter called scoreJson, which it passes to captureScores(). You then deserialize that string yourself once control reaches your method.

  • Will the parameter be significant here? Even if this is passed as a string, and that it corresponds to the right structure, it should get parsed successfully. I used the same JSON and the code snippet and was able to parse it successfully. – Jayant Das Aug 3 '18 at 13:46
  • I was too, Jayant, but the issue's not actually with the JSON - it's with how Salesforce is interpreting the JSON before it gets to @Walker's code. I can reproduce the original error when called as a REST service. It works fine in Anonymous Apex. – David Reed Aug 3 '18 at 13:49
  • I see what you are saying. I just tried it in a test class and not as external service. Good to verify it that way too. – Jayant Das Aug 3 '18 at 13:50
  • See my edit if you want to repro and see another workaround in Workbench. – David Reed Aug 3 '18 at 13:57
  • That's helpful! – Jayant Das Aug 3 '18 at 14:03
0

This worked :

@RestResource(urlMapping='/Imbellus/CandidateScore')
global with sharing class ImbellusScoreController {
    // workbench request URL : /services/apexrest/Imbellus/CandidateScore
    @HttpPost   
    global static String captureScores(ScoresList jsonScores) {
        System.debug('----No need to explicitly deserialize jsonScores----' + jsonScores);
        System.debug('----scoreLst----' + jsonScores.scores.size());
        return '';
    }
    global class ScoresList {
        global List<Score> scores;
    }
    global class Score {
        global String Overall_Behavioral_Score_c;
        global String Overall_Drive_Achieving_Score_c;
        global String Overall_Functional_Screen_Score_c;
        global String Overall_Leadership_Score_c;
        global String Interview_Overall_Score_c;
    }
}

/services/apexrest/Imbellus/CandidateScore

{
"jsonScores" : 
{
"scores" : 
[
{
"Overall_Behavioral_Score_c" : "50",
"Overall_Drive_Achieving_Score_c" : "60",
"Overall_Functional_Screen_Score_c" : "70",
"Overall_Leadership_Score_c" : "80",
"Interview_Overall_Score_c" : "90"
},
{
"Overall_Behavioral_Score_c" : "15",
"Overall_Drive_Achieving_Score_c" : "16",
"Overall_Functional_Screen_Score_c" : "17",
"Overall_Leadership_Score_c" : "18",
"Interview_Overall_Score_c" : "19"
}
]
}
}
0

This also worked

@RestResource(urlMapping='/Imbellus/CandidateScore')
global with sharing class ImbellusScoreController {
    // workbench request URL : /services/apexrest/Imbellus/CandidateScore
    @HttpPost   
    global static String captureScores(List<Score> scores) {
        System.debug('Score JSON: '+ scores);
        //List<Score> scoreLst = (List<Score>)JSON.deserialize(scoreJson, (List<Score>).class);
        System.debug('----scoreLst----' + scores);
        System.debug('----scoreLst----' + scores.size());
        return '';
    }
    public class ScoresList {
        public List<Score> scores;
    }
    global class Score {
        global Decimal creativity_score_c;
        global Decimal critical_thinking_score_c;
        global Decimal conceptual_thinking_score_c;
        global Decimal decision_making_score_c;
        global Decimal Imbellus_Overall_Score_c;
        global Id assessment_id;
    }
}



{
"scores" : 
[
{
"Overall_Behavioral_Score_c" : "50",
"Overall_Drive_Achieving_Score_c" : "60",
"Overall_Functional_Screen_Score_c" : "70",
"Overall_Leadership_Score_c" : "80",
"Interview_Overall_Score_c" : "90"
},
{
"Overall_Behavioral_Score_c" : "15",
"Overall_Drive_Achieving_Score_c" : "16",
"Overall_Functional_Screen_Score_c" : "17",
"Overall_Leadership_Score_c" : "18",
"Interview_Overall_Score_c" : "19"
}
]
}

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.