5

We are developing a managed package. By realizing that page layout for standard object will never be able to be pushed through package, I decide to use metadata API way, which means financialforce's api wrapper: https://github.com/financialforcedev/apex-mdapi

By noticing the lack of documentation, I pretty much followed the code in MetadataServiceExample.cls. So below is my code:

public static void addRelatedList()
{
    MetadataService.MetadataPort service = createService();

    MetadataService.Layout layout =
        (MetadataService.Layout) service.readMetadata('Layout',
            new String[] { 'Contact-Contact Layout' }).getRecords()[0];

    System.debug('layout is:' + layout);
    if(layout.relatedLists == null) {
        layout.relatedLists = new List<MetadataService.RelatedListItem>();
    }

    MetadataService.RelatedListItem new_related_list = new MetadataService.RelatedListItem();
    new_related_list.relatedList = 'Contact_List_Junction__c.Contact__c';
    new_related_list.customButtons = new List<String> {'Add_To_List'};
    new_related_list.fields = new List<String> {'Name', 'List__c'};
    //layout.relatedLists.add(new_related_list);

    handleSaveResults(
        service.updateMetadata(
            new MetadataService.Metadata[] { layout })[0]);
}

And got the following error:

Line: 10822, Column: 1 System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: UNKNOWN_EXCEPTION: An unexpected error occurred. Please include this ErrorId if you contact support: 1076527423-317733 (-258760784) faultcode=sf:UNKNOWN_EXCEPTION faultactor=

This exception really don't tell me anything useful. As you might have already noticed. I have already commented out the add related list into layout line. And I am still getting the error.

Also, the layout I have debugged, has the value relatedLists=null. And I definitely have some related lists in the contact-contact layout. So I guess it is where I read the layout is wrong.

Any suggestions?

Update Below are the requests sent I got from the debug log: retrieving:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <env:Header>
        <SessionHeader xmlns="http://soap.sforce.com/2006/04/metadata">
            <sessionId>00D28000001OSKz!AQ4AQOWyaF1WUNz2AZPtMY.APYbLhNRZiksgSv3FAIwfRC6cmN16s9wPiPTMU3orJ9hMtbqCcc_qmmu2tY7JCBdCb8RqDmWN</sessionId>
        </SessionHeader>
    </env:Header>
    <env:Body>
        <readMetadata xmlns="http://soap.sforce.com/2006/04/metadata">
            <type>Layout</type>
            <fullNames>Contact-Contact Layout</fullNames>
        </readMetadata>
    </env:Body>
</env:Envelope>

The one got the error:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <env:Header>
        <SessionHeader xmlns="http://soap.sforce.com/2006/04/metadata">
            <sessionId>00D28000001OSKz!AQ4AQOWyaF1WUNz2AZPtMY.APYbLhNRZiksgSv3FAIwfRC6cmN16s9wPiPTMU3orJ9hMtbqCcc_qmmu2tY7JCBdCb8RqDmWN</sessionId>
        </SessionHeader>
    </env:Header>
    <env:Body>
        <updateMetadata xmlns="http://soap.sforce.com/2006/04/metadata">
            <metadata xsi:type="Layout">
                <relatedLists>
                    <customButtons>Add_To_List</customButtons>
                    <fields>Name</fields>
                    <fields>List__c</fields>
                    <relatedList>Contact_List_Junction__c.Contact__c</relatedList>
                </relatedLists>
            </metadata>
        </updateMetadata>
    </env:Body>
</env:Envelope>
2
+50

I can't not reproduce your problem. But for each invalid data I can see clear exception description (API is 37). e.g. adding field Name will return:

MetadataServiceExamples.MetadataServiceExamplesException: Error occured processing component Job__c-Job Layout. Invalid field:Name in related list:Area__c.Job__c (FIELD_INTEGRITY_EXCEPTION)

While printing out existing layout you can see something like:

fields=(NAME, CREATED_DATE, weigth__c)

I think that you have to send standard fields in capital.

  • You probably have to use the same standard fields as what you would get from report describes. Not sure if you've ever looked at those? – Adrian Larson Sep 8 '16 at 23:59
  • This is a good point. +1 for this. However, my symptom is caused by another reason which I have already figured out. I will post my answer right down below. – Lance Shi Sep 9 '16 at 0:05
2

After several days' investigation and with Mohith Shrivastava's help in this question: How to fetch a layout from metadata API in apex under a name prefix . I have finally figured out what is happening.

The reason I have not fetched the correct data is because I am developing a managed package under a namespace. Sorry I didn't mention that in my question because I didn't know it could matter. And it doesn't matter in many situations as well, e.g. fetching dynamic metadata through schema.xxx.

So in short, in the developer org to fetch the layout, we need to follow this syntax:

MetadataService.Layout layout =
    (MetadataService.Layout) service.readMetadata('Layout',
                                                  new String[] { 'Contact-V6__Contact Layout' }).getRecords()[0];

Suppose V6 is the name prefix name here.

However, this only works in the dev org. If we need to make it work in the target/client org, we should still be using the existing version of grammar which is:

MetadataService.Layout layout =
    (MetadataService.Layout) service.readMetadata('Layout',
                                                  new String[] { 'Contact-Contact Layout' }).getRecords()[0];

Hope this can help other people with the same issue.

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.