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();
}
}