There are a few posts that describe to display the attachment's body through controller. My requirement is a little different- parse the contents and check for URL in the Attachment's body and display them. Also, there are other components in the page and therefore this is not a dedicated page to Attachments.

This is the snippet I'm working on:

            <apex:repeat var="cv" value="{!attachments}">
                    <td><a href="/servlet/servlet.FileDownload?file={!cv.id}">{!cv.Name}</a></td>

This returns, the error due to the Body field:

System.SObjectException: SObject row was retrieved via SOQL without querying the requested field

What would be the proposed way to parse the contents through VisualForce page? If this is not possible through VisualForce page, any other way to parse the contents?


Edit: After making modifications to the SOQL query, this is what I have under my Apex class:

public class ContentVersionAlt {

    public List<String> body {get; set;}

    public List<Attachment> getAttachments() {
        List<Attachment> attachments = [select id, Name, Description, ContentType, Body from Attachment];
        for(Attachment attachment : attachments)
        return attachments;

        public ContentVersionAlt() {
        body = new List<String>();

I'd like to have the data in the tabular format. For simplicity, let us assume that the body contains only a URL.

How can I access using the same list of repeat values in this scenario? I do not want to run multiple queries and that is the reason.

  • Modified my answer to better address your updated question. – dBeltowski Jun 1 '15 at 18:54

You get that error when you try to use a field that was not queried for.

Does attachments come from your custom controller, or is it the standard Salesforce Controller?

If you have a custom controller or extension check your SOQL to make sure it contains all fields you are trying to use.

If you are not using SOQL and are relying on the standard controller, try adding tags for each of your fields. This will ensure that the standard controller queries those fields.

You're on the right track, just know that the Body.toString() will only work with text documents.

I'd suggest using a wrapper class to hold the attachment and the String form of the body, and then iterating () over that.

public List<AttachmentWrapper> wrapper {get; private set;}

public YourController() {
    wrapper = new List<AttachmentWrapper>();

    for(Attachment a : [select id, Name, Description, ContentType, Body from Attachment])
        wrapper.add( new AttachmentWrapper(a) );

public class AttachmentWrapper
    public Attachment a {get; private set;}
    public String body {get; private set;}

    public AttachmentWrapper(Attachment at)
        this.a = at;
        this.body = at.Body.toString();

Visualforce page would look like this.

    <apex:repeat var="cv" value="{!wrapper}">
            <td><a href="/servlet/servlet.FileDownload?file={!cv.a.id}">{!cv.a.Name}</a></td>
|improve this answer|||||
  • Thank you, I've missed the field in the SOQL query. I'm quite new to this framework. Do I have to decode it and then parse the contents? What I could see here is core.filemanager.ByteBlobValue@3dd91c17 and the code under my class reads just of the SOQL query: select id, Name, Description, ContentType, Body from Attachment. – dmachop Jun 1 '15 at 16:18
  • @dmachop If you want to display any and all URL's in the Body, but not the Body itself, then yes you would need to decode the Body, and parse it in your Controller, save the URL's to a list of String and display the list. – dBeltowski Jun 1 '15 at 17:12
  • I've added more clarification on what I needed. I get that I can encode. But my output format should be along the same lines, the body field is a Base64encoded field and I'd like to get it on the fly. – dmachop Jun 1 '15 at 17:30

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.