Pages

Friday, November 19, 2010

Invoking a public Salesforce Web Service Method from a force.com site

Typically when dealing with a Salesforce hosted web service you need to first authenticate to the login site to get a sessionId and Url of the server that will process the requests.

It turns out that it is possible to invoke a web service without this authentication step provided it is configured in a certain way.

Step 1

Mark the class as global and the web service as public. E.g.

 /* 
 * Test to see if the web service can be connected to and used 
 * without having to log in as there is no api sObject use here.
 */
global class HelloWorld
{
    WebService public static String GetMessage()
    {
        return 'Hello world';
    }
}

Step 2

In Salesforce, it is important to give public access to the class (Adding the class under Settings > Develop > Sites > Public Access Settings)

Step 3

Download and import the WSDL from the Apex class.

Step 4

Once you have imported the WSDL you will need to use the public URL of the web service rather than the standard version which requires a session to be established first.

E.g. The domain will change to use the a pattern like:

https://<yourcompanyinsites>.<sandboxname>.<sandbo​xinstance>.force.com/<sitename>
https://<yourcompanyinsites>.secure.force.com/<sitename>

Step n+1

One of the key aspects when calling it from C# is setting ServicePointManager.Expect100Continue before creating the web service proxy. E.g.

System.Net.ServicePointManager.Expect100Continue = false;

See:

2 comments:

  1. It doesn't work. Got the following error,

    System.HttpResponse[Status=Internal Server Error, StatusCode=500]

    soapenv:ClientNo service available for class 'HelloWorld.GetMessage'

    ReplyDelete
  2. Hi,

    Is your web service in a managed package? You may or may not require the package prefix when referencing the class.

    See https://www.google.com/search?q=site%3Aboards.developerforce.com+%22No+service+available+for+class%22

    ReplyDelete