-->

Using apex:relatedList in a Visualforce page when

2019-08-13 00:06发布

问题:

I have two custom objects, Appointment and Session Report. Session Report is a child of Appointment in a standard Master-Detail relationship. Additionally, I have a profile, Student, which has Read-Create-Edit-Delete for Appointments and no rights for Session Reports. The use case is a Student can create an Appointment but cannot view the Session Reports created for this Appointment by a Tutor.

Using a standard layout for the Appointment object works as expected when viewing Appointments. Namely, the Student can see the Appointment fields and the related list of Session Reports is not displayed. All other user profiles observe can see the related list of Session Reports.

However, I have encountered a problem when replacing the standard layout with a Visualforce page as such:

<apex:page standardController="Appointment__c">
<apex:sectionHeader title="{!$ObjectType.Appointment__c.label}" subtitle="{!Appointment__c.Name}"/>
<apex:pageBlock title="{!$ObjectType.Appointment__c.label} Detail">
    <apex:pageBlockSection showHeader="false" columns="1">
        <apex:outputField value="{!Appointment__c.Tutor_Name__c}"/>
        <apex:outputField value="{!Appointment__c.Student_Name__c}"/>           
    </apex:pageBlockSection>
 </apex:pageBlock>    
 <apex:relatedList list="Session_Reports__r"/>

This new page works as expected for all users with at least Read rights for the Session Report object. The Student user has no rights to this object and receives this error message

'Session_Reports__r' is not a valid child relationship name for entity Appointment 

Clearly this relationship does exist as the page can be displayed properly for users with different profiles. I have been unable to resolve the difference between the standard layout and the VF page that would result in this failure. It has been suggested to me that I could identify the user profile in the VF page and use that information to toggle rendering. However, this type of approach defeats the purpose of the Salesforce security model and I won't be adopting such a technique.

Should I be able to use apex:relatedList in this fashion? Or have I wrongly assumed that the VF rendering engine could figure out when it can and cannot display related lists?

回答1:

Salesforce security model is only going to ensure you don't show data that is not accessible to a particular user. How it does this is by throwing that exception you see. If you're building a custom vf page your responsible for making sure you don't display something the user isn't allowed to see. Note this is different than for fields which just don't show up if the user doesn't have the proper field level security.

You'll need to add a check to verify a user can view that object. Fortunately they have a lot of "is" methods (isAccessible, isCreatable, isDeletable, etc.) on the Describe Object Result for you to determine what the current user's permissions are for that object without having to hard code profiles into your code. For your specific case you don't what to display that related list if it's object not accessible.

Visualforce Page:

<apex:relatedList list="Session_Reports__r" 
                  rendered="{!$ObjectType.Session_Report__c.accessible}"/>