1

I am trying to fetch all the attachments for a record from salesforce by .Net webservice.

Below is the code which i am trying to do. If i am fetching a single attachment, i am not facing any issue. But if there are multiple attachment,i am unable to fetch and i am getting the below error -

'System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at WcfService1.Service1.ConnectSalesforce() in C:\Users\mohapats\source\repos\WcfService1\WcfService1\Service1.svc.cs:line 149
   at WcfService1.Service1.CombineMultiplePDFs(List`1 InFiles, String OutFile) in C:\Users\mohapats\source\repos\WcfService1\WcfService1\Service1.svc.cs:line 59'

c# code -

if(currentLoginResult.sessionId != null)
            {
                QueryResult queryResult = null;
                String SOQL = "SELECT Id FROM Attachment where ParentId = '0010v0000071CHp'";
                queryResult = sfdcBinding.query(SOQL);
                List<String> ids = new List<String>();

                if (queryResult.size > 0)
                {
                    for(int i = 0; i < queryResult.size; i++) { 

                    Attachment readAttatchmentId = (Attachment)queryResult.records[i];
                    ids.Add(readAttatchmentId.Id);
                    }
                }

                if(ids.Count > 0)
                {
                    //QueryResult queryResult1 = null;
                    //String SOQL1 = "SELECT Id,Body,Name FROM Attachment where Id = '" + ids + "'";
                    //queryResult1 = sfdcBinding.query(SOQL1);
                    String query = "SELECT Id,Body,Name FROM Attachment ";

                    String strIds = "";
                    foreach (String  id in ids)
                    {
                        if (strIds.Equals(""))
                        {
                            strIds = "'" + id + "'";
                        }
                        else
                        {
                            strIds += ",'" + id + "'";
                        }
                    }
                    query += "where id in (" + strIds + ")";

                    QueryResult result = sfdcBinding.query(query);
                                        Boolean done = false;



 if (result.size > 0)
                {
                    while (!done)
                    {
                        sObject[] records = result.records;
                        for (int i = 0; i < records.Length; ++i)
                        {
                            Attachment q = (Attachment)records[i];

                        }
                        if (result.done)
                        {
                            done = true;
                        }
                        else
                        {
                            result = sfdcBinding.queryMore(result.queryLocator);
                        }
                    }

                }

The below soql -

QueryResult result = sfdcBinding.query(query);

This should return two arrays

result.records[0] & result.records[1]

but it is returning only one

result.records[0]

but result.size is showing as 2

So at the below line

Attachment q = (Attachment)result.records[i];

when it comes for the 2nd time, it throws the above error.

  • problem is that result and result[i].record can have different length. It is exactly what happens in your c# code – kurunve Oct 6 '17 at 20:17
  • Hi kurunve.. is there any way to resolve this.. – learningmode Oct 6 '17 at 20:26
3

You've run into the query result paging where the size of the SOQL query result size will be greater than then number of records returned in the current QueryResult.

When dealing with Attachments it's not uncommon for the QueryResult to only have a single record.

The query result object contains up to 500 rows of data by default. If the query results exceed 500 rows, then the client application uses the queryMore() call and a server-side cursor to retrieve additional rows in 500-row chunks. You can increase the default size up to 2,000 in the QueryOptions header. For more details see Change the Batch Size in Queries in the Force.com SOQL and SOSL Reference. [Source]

You need to check if done is true. If not, use the queryLocator to fetch the next lot of results until done turns false.

See:

  • Hi Daniel.. Can u check the above code and let me know if i have written correctly... i have updated it.. – learningmode Oct 6 '17 at 20:43
  • @learningmode Your initial queryResult isn't checking if it is done and seems a bit redundant. Why not just perform a single SOQL query to get the attachments (with the body field) based on the ParentId? Otherwise, yes, from what I can see it should work through all the query results. – Daniel Ballinger Oct 8 '17 at 22:21
0

Why not just loop through the result rows directly and avoid potential indexing errors altogether?

if(result.size() > 0){
    for(sObject record : result.records){
        Attachment q = (Attachment)record;
        ...
    }
}
  • Hi .. RenegadeCoder.. after updating my code.. i am still getting only 1 record in my array.. – learningmode Oct 6 '17 at 20:26

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.