Получить экземпляр экземпляра Salesforce вместо экземпляра visualforce

На странице visualforce мне нужно получить URL-адрес экземпляра нашей организации salesforce, а не URL-адрес визуальной силы.

Например, мне нужно https://cs1.salesforce.com вместо https://c.cs1.visual.force.com

Вот что я пробовал до сих пор и результат, который я получил:

Доступ к глобальной переменной сайта с страницы VF:

<apex:outputText value="{!$Site.Domain}" /> возвращает null

Sidenote: Кажется, что все в $Site.xxx возвращает null.

От контроллера Apex:

public String getSfInstance()
{
  return ApexPages.currentPage().getHeaders().get('Host');
}

и

public String getSfInstance()
{
  return URL.getSalesforceBaseUrl().toExternalForm();
}

возвращает c.cs1.visual.force.com и https://c.cs1.visual.force.com соответственно.

Вопрос: Как получить то, что я хочу: https://cs1.salesforce.com?

Ответ 1

Здесь что-то, что я использовал в моем Apex Trigger

System.URL.getSalesforceBaseUrl().getHost().remove('-api' );

Это дает мне правильный URL

Ответ 2

Это известная проблема, URL.getSalesforceBaseUrl() должна предоставить эту информацию, но это не так. Однако на самом деле это имеет очень ограниченное функциональное воздействие.

Их экземпляры и вершинные домены взаимозаменяемы в том смысле, что запрос URL-адреса, который не принадлежит одному, перенаправляется на другой.

например, если вы ищете /apex/myPage из cs1.salesforce.com, вы получите перенаправление на c.cs1... и запрос/идентификатор vise versa/ID из домена apex перенаправит вас в домен экземпляра (если только подробное действие был отменен)

Если это не поможет вам, есть одно обходное решение, хотя и очень уродливое: создать пользовательский объект для хранения базового url и создать перед триггером insert/update, который установит поле baseURL в URL.getSalesforceBaseUrl().toExternalForm(). Очевидно, триггер - это единственное место на платформе, где это будет работать (кроме анонимного исполнения, которое не очень полезно). При настройке приложения вставьте что-то в эту таблицу, а затем используйте SOQL для извлечения базового url.

Ответ 3

Вот свойство Apex, которое вы можете ввести в класс Utility, который будет надежно возвращать экземпляр для вашей организации. Используя это, вы можете легко создать свою URL-адрес Salesforce вашей организации, добавив ".salesforce.com" в экземпляр:

public class Utils {

 // Returns the Salesforce Instance that is currently being run on,
 // e.g. na12, cs5, etc.
public static String Instance {
    public get {
        if (Instance == null) {
            //
            // Possible Scenarios:
            //
            // (1) ion--test1--nexus.cs0.visual.force.com  --- 5 parts, Instance is 2nd part
            // (2) na12.salesforce.com      --- 3 parts, Instance is 1st part
            // (3) ion.my.salesforce.com    --- 4 parts, Instance is not determinable

            // Split up the hostname using the period as a delimiter
            List<String> parts = System.URL.getSalesforceBaseUrl().getHost().replace('-api','').split('\\.');
            if (parts.size() == 3) Instance = parts[0];
            else if (parts.size() == 5) Instance = parts[1];
            else Instance = null;
        } return Instance;
    } private set;
}

// And you can then get the Salesforce base URL like this:
public static String GetBaseUrlForInstance() {

     return 'https://' + Instance + '.salesforce.com';

}

FYI: для сценария (1) первое имя хоста из 4 частей может стать очень сложным, но вы всегда сможете найти имя экземпляра в качестве второй части. Для тех, кто заинтересован, синтаксис сценария 1 следует этому шаблону:

     <MyDomain>--<SandboxName>--<Namespace>.<Instance>.visual.force.com

Ответ 4

Здесь у вас есть довольно хороший и небольшой фрагмент, который делает, что нужно для VisualforcePages: -)

        String sUrlRewrite = System.URL.getSalesforceBaseUrl().getHost();
        //  Example: c.cs7.visual.force.com
        sUrlRewrite = 'https://'
                + sUrlRewrite.substring(2,6) 
                + 'salesforce.com'
                + '/'
                + recordId;

//Возвращает: https://cs7.salesforce.com/00kM00000050jFMIAY

Ответ 5

Это неудачный недостаток платформы. GetSalesforceBaseUrl() содержит оговорки, включая:

  • возвращаемый протокол (http vs https) непоследовательный,
  • контекст visualforce влияет на результат (как вы видели с субдоменом)
  • Использование моего домена и песочницы также влияет на результат, делая манипуляции с строкой рискованными,

Единственный надежный способ получить истинную конечную точку pod/instance - использовать API идентификации Salesforce.

Здесь memoized static, который можно использовать, что смягчает все перечисленные выше факторы:

/**
 * Determines the true API hostname for a Salesforce org using the Identity API.
 * eg 'https://pod.salesforce.com' (most orgs)
 * eg 'https://custom.my.salesforce.com' (my domain)
 * eg 'https://custom--dev.pod.my.salesforce.com' (sandbox orgs)
 */
static public String protocolAndHost {
    get {
        if (protocolAndHost == null) {
            //memoize
            String uid = UserInfo.getUserId();
            String sid = UserInfo.getSessionId();
            String oid = UserInfo.getOrganizationId();
            String base = Url.getSalesforceBaseUrl().toExternalForm();

            //use getSalesforceBaseUrl within batches and schedules (not Visualforce), and fix inconsistent protocol
            if (sid == null) return base.replaceFirst('http:', 'https:');

            //within test context use url class, else derive from identity response
            PageReference api = new PageReference('/id/' + oid + '/' + uid + '?access_token=' + sid);
            String content = Test.isRunningTest() ? '{"urls":{"profile":"' + base + '"}}' : api.getContent().toString();
            Url profile = new Url(content.substringBetween('"profile":"', '"'));
            protocolAndHost = profile.getProtocol() + '://' + profile.getHost();
        }
        return protocolAndHost;
    }
}

Ответ 6

Исправление к фрагменту Alex_E:

    String sUrlRewrite = System.URL.getSalesforceBaseUrl().getHost();
    String sfBaseProtocol = System.URL.getSalesforceBaseUrl().getProtocol();

    //remove namespace
    integer firstDotPos = sUrlRewrite.indexOf('.');
    sURlRewrite = sURlRewrite.substring(firstDotPos+1);

    //replace visual.force with salesforce
    sURlRewrite = sURlRewrite.replace('visual.force', 'salesforce');
    sUrlRewrite = sfBaseProtocol+'://'+sURlRewrite;

serverURL = sUrlRewrite;

Ответ 7

Это работает для меня:

String sUrlRewrite = System.URL.getSalesforceBaseUrl().getProtocol() 
    + '://' + System.URL.getSalesforceBaseUrl().getHost() 
    + '/' + record.Id;

Ответ 8

Вот как это сделать с regex

public String getURL() {
    return String.format(
      'https://{0}.salesforce.com',
      new String[]{
        URL.getSalesforceBaseUrl().getHost().substringAfter('.').substringBefore('.')
      });
}