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: