certinia / apex-mdapi

Apex Wrapper for the Salesforce Metadata API
BSD 3-Clause "New" or "Revised" License
685 stars 975 forks source link

Unable to read layout information #91

Closed avinashega closed 9 years ago

avinashega commented 9 years ago

Hi,

I have created a new layout for a custom object that is from an installed package. In this case, the fullName of the layout will be : NamespaceCustom_Object_namec-Layout_Name

I tried the below code but it returns a blank response.

service.readMetadata('Layout', new String[] { 'namespace__my_object__c-My Layout'}).getRecords();

The request that goes out:

<?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>00D1a000000YEEq!AQUAasjQwB3H_FsiVAN4ohyYcGjPsRG8S4hiEWHzOE17Qrc88zsPgLfwaaXQIvWhA9h4vgrMeqvfVke4.63lvevKvYsSFyB9</sessionId></SessionHeader></env:Header><env:Body><readMetadata xmlns="http://soap.sforce.com/2006/04/metadata"><type>Layout</type><fullNames>namespace__my_object__c-My Layout</fullNames></readMetadata></env:Body></env:Envelope>

The response:

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/2006/04/metadata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><readMetadataResponse><result><records xsi:nil="true"/></result></readMetadataResponse></soapenv:Body></soapenv:Envelope>

But, when I call listMetadata(), I can see that layout in the response.

afawcett commented 9 years ago

Take a look at Q&A number 4 on this blog.

avinashega commented 9 years ago

Yep. that didn't really help. I'm assuming it's an issue at salesforce's end.

afawcett commented 9 years ago

If you login via Developer Workbench and review the fullName via the Metadata listing UI in that tool, what does it show?

avinashega commented 9 years ago

In my case I'm getting 'geneapplicationsc-portal'. where gene is the namespace of the package and applications__c is the custom object from the package and 'portal' is a layout that I have created on the object in my org.

I can see it in the listmetadata response as well. but when I try to retrieve it, I get a blank response.

afawcett commented 9 years ago

I'm starting to wonder if this is a bug in the Metadata API.... :-1:

My suggestion would then be to copy paste the SOAP request and use it as repo steps in case.

(avoiding Salesforce support getting distracted with the Apex wrapper).

Please do let me know how you get on if you take this route, really sorry i've run out of ideas on this one.

jeffhube commented 7 years ago

I've opened a case for this issue - being unable to retrieve unmanaged layouts on managed objects using readMetadata(). It does work if I use retrieve() instead, but that requires a visualforce page or external service to handle the zip files.

afawcett commented 7 years ago

Thanks @jeffhube for the update, any news?

Sheing commented 7 years ago

Having the same problem where readmetadata couldn't read a page layout that I created inside a installed package. For example: readmetadata is able to do this--> readMetadata("Layout", new string[] { "SFCustom_Objectc-SFLayoutName" }); for installed layout, but I can't do this--> readMetadata("Layout", new string[] { "SF__Custom_Objectc-America" }) I'd tried debugging and tried using 2 namespaces but it's not working. Let me know if you can use readmetadata to read layout created inside layout package.

afawcett commented 7 years ago

Have a look at my FAQ blog post (linked on the README) i have some tips in that i believe.

Sheing commented 7 years ago

Hi Andrew, Thanks for you efficient reply.

So in the README markdown you used new String[] { sFolderApiName+'/'+sReportApiName } I had tried using the apifolder name like--> new string[] {"layouts/SFCustom_ObjectC-America"} and also tried double namespace --> new string[] {"layouts/SFCustom_ObjectC-SF__Ameria"} and it still didn't work.

My only solution to this problem right now is to retrieve that specific layout XML file, deserialize XML file to type "Layout" and cast it to Metadata.Layout.

e.g: MetadataService.Layout Layout = (MetadataService.Layout)DeserializeXMLFileToObject(America.XML); I believe this is an internal bug inside invoke method.

Note: I am using C# to program this.

afawcett commented 7 years ago

Ah i see, @Sheing, your using .net, i had not appreciated that. I think the underlying issue with managed layouts and the Metadata API plagues us regardless of .net or apex tbh. I'm glad you've got it moving, i assume via the 'retrieve' API?

Sheing commented 7 years ago

@afawcett Yeap I am using the retrieve Metadata API to get the specific layout created inside the installed package. As of now, it works fine but it will be something hard to maintain in the future considering I have to retrieve that particular layout to do something in my web app. Anyway, thanks for the reply, I appreciate that.

afawcett commented 7 years ago

No problem. Meanwhile try the Apex Native MD API, see if that works for you?