Intellipaat Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in Salesforce by (11.9k points)

Hi, I am trying to create an apex rest service but getting error Invalid type for Http* method: system.RestRequest

Here is the function where I am getting this error.

@RestResource(urlMapping='/v.9/scorecard/*') 

global with sharing class ScorecardRestSvc {

  /**

  * @date July 26, 2011

  * @description Update a question answer. 

  * @return Map<String,String> - results and boolean success message

  */

  @HttpPost

  global Static Map<String,String> doPut(RestRequest req, RestResponse res) {

    String answerId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);

    string updateResult = 'Waiting to run';

    Map<String,String> returnMap = new Map<String,String>();

    returnMap.put('Success','True');

    // mark the participant as having no submission

      if(req.params.containsKey('deleteSubmission') && req.params.get('deleteSubmission').toLowerCase() == 'true') {

      markParticipantAsNoSubmission(req,res);

        returnMap.put('Message','Participant marked as no submission.');

        return returnMap;    

      } 

    try {

      if(!isValidId(answerId) || answerId.length() == 0) {

        returnMap.put('Method','Bulk');

        updateResult = updateObjectsFromXml(req,res);     

      } else {

        returnMap.put('Method','Single');

        updateResult = updateSingleAnswer(req,res);

      }

      returnMap.put('Update Result', updateResult);

      if(updateResult != 'All records updated successfully. ' && updateResult != 'All records updated successfully. Survey set to scored. No further changes allowed') {

        returnMap.put('Success','False');

      }     

    } catch(Exception e) {

      returnMap.put('Error',e.getMessage());

    } 

    return returnMap;   

  }

  private static void markParticipantAsNoSubmission(RestRequest req, RestResponse res) { 

    ID participantId = (ID)req.params.get('participantId');

    // get the participant and mark them as no submission

    Challenge_Participant__c cp = [select id, Has_Submission__c from Challenge_Participant__c 

      where id = :participantId];

    cp.Has_Submission__c = false;

    cp.Status__c = 'Submission Rejected';

    update cp;      

  }

  private static String updateObjectsFromXml(RestRequest req, RestResponse res) {

    string returnMessage = 'All records updated successfully. ';

    try {

      String xml = req.requestBody.toString().trim();

      System.debug('===================== here is the xml passed: ' + xml);

      List<sObject> updateList = parseUpdateXML(xml);

      //before we update we need to make sure this card is not scored

      List<QwikScore_Question_Answer__c> thisAns = [select QwikScore_Scorecard__r.Scored__c, QwikScore_Scorecard__c 

        from QwikScore_Question_Answer__c where id = :updateList[0].Id];

      if(thisAns[0].QwikScore_Scorecard__r.Scored__c) throw new customException('This scorecard has been marked as scored. No further updates are available.');

     // ScoringEngine.saveAnswers(thisAns[0].QwikScore_Scorecard__c, updateList);           

      if(req.params.containsKey('setScored') && req.params.get('setScored').toLowerCase() == 'true') {

      //  ScoringEngine.gradeScorecard(thisAns[0].QwikScore_Scorecard__c);

        returnMessage += 'Survey set to scored. No further changes allowed';        

      }

    } catch(Exception e) {

      returnMessage = e.getMessage();

    }

    return returnMessage;

  }

  private static String updateSingleAnswer(RestRequest req, RestResponse res) {

    String answerId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);

    // get a map of all field in the member__c custom object

    Map<String, Schema.SObjectField> sObjectFieldsMap = Schema.SObjectType.QwikScore_Question_Answer__c.fields.getMap();

    // don't let them update the following fields -- use all lowercase for comparison

    Set<String> noUpdateFields = new Set<String>{'Answer_Value__c,QwikScore_Scorecard__c,Weighted_Score__c,Answer_Value__c,IsAnswered__c'};

    String returnMessage = 'All records updated successfully. ';

    try {

      QwikScore_Question_Answer__c qa = new QwikScore_Question_Answer__c(Id=id.ValueOf(answerId));

      for (String key : req.params.keySet()) {

        // only add params if they are valid field on the object and not on the no-update list

        if (sObjectFieldsMap.containsKey(key) && !noUpdateFields.contains(key.toLowerCase()))

          qa.put(key,req.params.get(key)); 

      }

      List<QwikScore_Question_Answer__c> thisAns = [select QwikScore_Scorecard__r.Scored__c,

        QwikScore_Scorecard__c from QwikScore_Question_Answer__c where id = :qa.Id];

      if(thisAns.isEmpty()) throw new customException('Could not locate answer with Id' + qa.Id);

      if(thisAns[0].QwikScore_Scorecard__r.Scored__c) throw new customException('This scorecard has been marked as scored. No further updates are available.');

      //ScoringEngine.saveAnswers(thisAns[0].QwikScore_Scorecard__c, new List<QwikScore_Question_Answer__c>{qa});

      if(req.params.containsKey('setScored') && req.params.get('setScored').toLowerCase() == 'true') {

        //ScoringEngine.gradeScorecard(thisAns[0].QwikScore_Scorecard__c);

        returnMessage += 'Scorecard set to scored. No further changes allowed';          

      }

    } catch(Exception e) {

      returnMessage = e.getMessage();

    }

    return returnMessage;     

  }

  /*******************************************

  Used to create a list of sObjects ready for updating from 

  XML data that would likely be passed in a request

  This method is pretty cool actually. You can pass it some XML

  formated in the way outlined previously and it will get you a list

  of objects ready for update. I think they all have to be of the same type

  though.

  *******************************************/

  private static List<sObject> parseUpdateXML(String Xml) {

    Map<Id,sObject> updates = new Map<Id,sObject>();  

    xml = xml.trim();

    Xmlstreamreader reader = new Xmlstreamreader(xml);

    Id lastId;

    string fieldName;

    Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();

    Schema.SobjectType oType;

    while (reader.hasNext()) {

      if (reader.getEventType() == XmlTag.START_ELEMENT && reader.getLocalName().toLowerCase() == 'object') {

        if(oType == null) oType = gd.get(reader.getAttributeValueAt(0));

        sObject thisObject;

        if(reader.getAttributeLocalName(1) == 'id') thisObject= oType.newSObject(reader.getAttributeValueAt(1));

        if(thisObject != null) {

          updates.put(thisObject.id,thisObject);

          lastId = thisObject.id;

        }

      } else if(reader.getEventType() == XmlTag.START_ELEMENT && reader.getLocalName().toLowerCase() == 'field') {

        fieldName = reader.getAttributeValueAt(0);

        sObject thisObject = updates.get(lastId);

        reader.next();

        thisObject.put(fieldName,getDecodedString(reader));

        updates.put(thisObject.id,thisObject);  

      }

    reader.next();

    }

    return updates.values();

  }

  /*******************************************

  Test to see if a given string is a valid id

  ********************************************/

  public static Boolean isValidId(String s) {

    Id validId;

    try {

      validId = s;

      return true; 

    } catch (Exception ex) {

      return false;

    }

  } 

  public class customException extends Exception {}

  public static String getDecodedString(Xmlstreamreader reader) {

    return EncodingUtil.urlDecode(reader.getText(), 'UTF-8').trim();

  }

}

can any one please tell why i am getting this error and how to rectify it?

1 Answer

0 votes
by (32.1k points)

A way that RestRequest and RestResponse are accessed is changed in the API version 24.0. Because of this change, any code with version 24.0 or later needs to access them by using new RestContext object. 

Here is the new way of doing so:

@HttpPost

global Static Map<String,String> doPut() {

    RestRequest req = RestContext.request;

    RestResponse res = RestContext.response;

The old way for the same for version below 24.0 is:

@HttpPost

global Static Map<String,String> doPut(RestRequest req, RestResponse res) {

31k questions

32.8k answers

501 comments

693 users

Browse Categories

...