Q:

JSON Formatting error

I have a requirement wherein I have to strictly format the body of the request as below.
{
  "body":  "* Case Number: 1406800\n* Primary Contact Name: Larry Brown Portal \n* Test:SampleTest"

}

Where case information is passed as multi line string with 'new line' in a single key. I tried with following up code but I am not able to achieve what I wanted.
String caseBody,oName;
Case  c = [SELECT Id,Account.Name,CaseNumber,CreatedDate,SamanageESD__RequesterName__c,Description,Owner.Name FROM Case WHERE Id=: caseValues.get(0).caseID];
if(c != null){
    Map<String,String>cMap = new Map<String,String>();
    cMap.put('Click here to view request',URL.getSalesforceBaseUrl().toExternalForm() + '/' + c.Id);
    cMap.put('Description',c.Description);
    cMap.put('Office',c.Account.Name);
    cMap.put('CreatedDate',String.valueOf(c.CreatedDate));
    cMap.put('Primary Contact Name',c.SamanageESD__RequesterName__c);
    cMap.put('Case Number',c.CaseNumber);
    Map<String,Map<String,String>> bMap = new Map<String,Map<String,String>>();
    bMap.put('body',cMap);
    caseBody = JSON.serialize(bMap);
    oName = c.Owner.Name;   
}

19:21:36.52 (90593432)|USER_DEBUG|[15]|DEBUG|@@case_body==>{"body":{"Case Number":"1406800","Primary Contact Name":"Larry Brown Portal"}}

How would I achieve the format and wondering what I am missing here.

A:

It looks like it is just one key ("body") and one value (the long string) from what you pasted.
So you'd build the long string the way you'd like and then put it in the map one time before serializing.
String bodyJson = '';
Case  c = [SELECT Id,Account.Name,CaseNumber,CreatedDate,SamanageESD__RequesterName__c,Description,Owner.Name FROM Case WHERE Id=: caseValues.get(0).caseID];
if(c != null){
    jsonBody += 'Description: ' + c.Description + ' \\n* ';
    jsonBody += 'Office: ' + c.Office) + ' \\n* ';
//rest of the fields following the same format
    bMap.put('body',bodyJson);
    caseBody = JSON.serialize(bMap);
}

To avoid having to edit the class every time you could look at using a fieldSet to store all the fields that'll be in the json. You can dynamically build the SOQL query to pull all fields listed in the fieldSet.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_fieldsets_describe.htm
public List<Schema.FieldSetMember> getFields() {
    return SObjectType.Case.FieldSets.jsonFields.getFields();
}

public Case getCase(Id caseId) {
    String query = 'SELECT ';
    for(Schema.FieldSetMember f : yourclass.getFields()) {
        query += f.getFieldPath() + ', ';
    }
    query += 'Id, Name FROM Case WHERE Id = \'' + caseId + '\'';
    return Database.query(query);
}

Those could be separate methods you use in your logic below to pull all the field names in the field set and pull the value from the case record.
String bodyJson = '';
Case  c = yourclass.getCase(caseValues.get(0).caseID);
if(c != null){
   for(Schema.FieldSetMember f : yourclass.getFields()) {
        jsonBody += c.getField(f.getFieldPath()) + ' \\n* ';
    }
    caseBody = JSON.serialize(bMap);
}

