function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
TerryLuschenTerryLuschen 

Help with Windows Phone connecting to Salesforce Enterprise API

Hi!

I am trying to call the Enterprise Web Service in Salesforce on my Dev org.
I have the login working correctly, but when I try to make the next call to retrieve I am getting an error.

I was using this great article as a reference:
http://www.developer.com/net/net/salesforce-integration-with-.net-web-services-soap-api-.html?comment=53310-5710

I am trying to do this on a Windows Phone Application through Microsoft Visual Studio 2010 Express for Windows Phone.
This means when I do the 'Add Service References' option and I specify my wsdl that I do not get a wrapper class for setting my metadata URL and the Session ID.
I think my problem is that I do not have my Session ID set in the header section of the Soap Request.
I think I have the metadata URL set properly in the new EndPointAddress that I created.
In Windows Phone I have to make all calls asynchronously, which then makes me specify a callback method.

 

Here is my endpoint in the Services.ClientConfig file for the initial login call:
<endpoint address="https://login.salesforce.com/services/Soap/c/21.0"
   binding="basicHttpBinding" bindingConfiguration="SoapBinding1"
   contract="SForceServiceE.Soap" name="SoapE" />

 

Here is the exception...

Message "No operation available for request {urn:enterprise.soap.sforce.com}retrieve" string
Stack Trace:
  StackTrace "   at System.ServiceModel.DiagnosticUtility.ExceptionUtility.BuildMessage(Exception x)\r\n   at System.ServiceModel.DiagnosticUtility.ExceptionUtility.LogException(Exception x)\r\n   at System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(Exception e)\r\n   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)\r\n   at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)\r\n   at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)\r\n   at YouTubeSearch.SForceServiceE.SoapClient.SoapClientChannel.Endretrieve(IAsyncResult result)\r\n   at YouTubeSearch.SForceServiceE.SoapClient.YouTubeSearch.SForceServiceE.Soap.Endretrieve(IAsyncResult result)\r\n   at YouTubeSearch.SForceServiceE.SoapClient.Endretrieve(IAsyncResult result)\r\n   at YouTubeSearch.SForceServiceE.SoapClient.OnEndretrieve(IAsyncResult result)\r\n   at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)\r\n   at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)\r\n   at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously, Exception exception)\r\n   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.CallComplete(Boolean completedSynchronously, Exception exception)\r\n   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishSend(IAsyncResult result, Boolean completedSynchronously)\r\n   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.SendCallback(IAsyncResult result)\r\n   at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)\r\n   at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously, Exception exception)\r\n   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.OnGetResponse(IAsyncResult result)\r\n   at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClassa.<InvokeGetResponseCallback>b__8(Object state2)\r\n   at System.Threading.ThreadPool.WorkItem.doWork(Object o)\r\n   at System.Threading.Timer.ring()\r\n" string

 

Here is the Soap Request...

Request {<?xml version="1.0" encoding="utf-16"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <retrieve xmlns="urn:enterprise.soap.sforce.com">
      <fieldList>Name</fieldList>
      <sObjectType>Game__c</sObjectType>
      <ids>
        <string>a00E0000000iaEcIAI</string>
      </ids>
    </retrieve>
  </s:Body>
</s:Envelope>} System.ServiceModel.Channels.Message {System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage}


Here is the Soap Reply...

Reply {<?xml version="1.0" encoding="utf-16"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" />
  <soapenv:Body>
    <soapenv:Fault>
      <faultcode>soapenv:Client</faultcode>
      <faultstring>No operation available for request {urn:enterprise.soap.sforce.com}retrieve</faultstring>
    </soapenv:Fault>
  </soapenv:Body>
</soapenv:Envelope>} System.ServiceModel.Channels.Message {System.ServiceModel.Channels.BufferedMessage}

 

Here is the code I am using...

private void BuildClassFromSalesForce2()
        {
            SForceServiceE.SoapClient myClientR = new SForceServiceE.SoapClient("SoapE");
            myClientR.loginAsync("MyEmail", "MyPasswordMySecurityToken");

            myClientR.loginCompleted += new EventHandler<SForceServiceE.loginCompletedEventArgs>(soapLoginCompleted2);

        }

        private void soapLoginCompleted2(object src, SForceServiceE.loginCompletedEventArgs myArg)
        {

            var elements = new List<System.ServiceModel.Channels.BindingElement>();
            elements.Add(new System.ServiceModel.Channels.TextMessageEncodingBindingElement(
                System.ServiceModel.Channels.MessageVersion.Soap11, System.Text.Encoding.UTF8));
            elements.Add(new System.ServiceModel.Channels.HttpsTransportBindingElement());
            System.ServiceModel.Channels.CustomBinding myBinding = new System.ServiceModel.Channels.CustomBinding(elements);

            System.ServiceModel.EndpointAddress myEndPoint = new System.ServiceModel.EndpointAddress(myArg.Result.metadataServerUrl);
            //Where do I set myArg.Result.sessionId?
            //doesn't this need to get into a session header in the Request SOAP message like this?   How do I do this?
            //<soapenv:Header>
            //    <urn:SessionHeader>
            //        <urn:sessionId>xxxxxx</urn:sessionId>
            //    </urn:SessionHeader>
            //</soapenv:Header>
           
            SForceServiceE.SoapClient myRetrieveClient = new SForceServiceE.SoapClient(myBinding, myEndPoint);
           
            myRetrieveClient.retrieveCompleted += new EventHandler<SForceServiceE.retrieveCompletedEventArgs>(soapRetrieveCompleted2);
            string[] ids = new string[1];
            ids[0] = "a00E0000000iaEcIAI";
            myRetrieveClient.retrieveAsync("Name", "Game__c", ids, myArg.UserState);
        }


        private void soapRetrieveCompleted2(object src, SForceServiceE.retrieveCompletedEventArgs myArg)
        {
            //It never gets to here.  It errors out in SForceServiceE.retrieveResponse
            MessageBox.Show("Retrieve Completed!  Count: " + myArg.Result.Length);
        }

 

 Here is where it is erroring out:
 public YouTubeSearch.SForceServiceE.retrieveResponse Endretrieve(System.IAsyncResult result) {
                object[] _args = new object[0];
  //Error here!
                YouTubeSearch.SForceServiceE.retrieveResponse _result = ((YouTubeSearch.SForceServiceE.retrieveResponse)(base.EndInvoke("retrieve", _args, result)));
                return _result;
            }


What am I doing wrong? 

One of the articles said this error is causing by referencing the Enterprise wsdl, but calling the partner API.  Am I doing this?

Thanks!

Best Answer chosen by Admin (Salesforce Developers) 
SuperfellSuperfell

Its not the namespace in retreive (which is correct), its this part

 

      <ids>
        <string>a00E0000000iaEcIAI</string>
      </ids>

 

it should be

 

      <ids>a00E0000000iaEcIAI</ids>

 

Have you thought of using the REST API instead ?

All Answers

SuperfellSuperfell

What URL are you sending the request to ?

TerryLuschenTerryLuschen

Simon,

 

Here is the value of myArg.Result.metadataServerUrl that I use when creating the Request object after the Login is complete.

 

 "https://na9-api.salesforce.com/services/Soap/m/21.0/00DE0000000Hjbh"

 

System.ServiceModel.EndpointAddress myEndPoint = new System.ServiceModel.EndpointAddress(myArg.Result.metadataServerUrl);

 

Is that the URL you wanted to see?

 

Thanks!

 

Terry Luschen



SuperfellSuperfell

Yes, that's the wrong url, you should be using Result.serverUrl

TerryLuschenTerryLuschen

Thanks!  I think I am farther now with serverUrl instead of metadataServerUrl.

 

I am now getting this error

Invalid Session ID found in SessionHeader: Illegal Session

 

I think this brings me back a question in my original post.  

Where do I set myArg.Result.sessionId?
Doesn't this need to get into a session header in the Request SOAP message like this?   How do I do this?   This is very much a c# .net question I know.

 

Here is the SOAP response

+        Reply    {<?xml version="1.0" encoding="utf-16"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sf="urn:fault.enterprise.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" />
  <soapenv:Body>
    <soapenv:Fault>
      <faultcode>sf:INVALID_SESSION_ID</faultcode>
      <faultstring>INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session</faultstring>
      <detail>
        <sf:UnexpectedErrorFault xsi:type="sf:UnexpectedErrorFault">
          <sf:exceptionCode>INVALID_SESSION_ID</sf:exceptionCode>
          <sf:exceptionMessage>Invalid Session ID found in SessionHeader: Illegal Session</sf:exceptionMessage>
        </sf:UnexpectedErrorFault>
      </detail>
    </soapenv:Fault>
  </soapenv:Body>
</soapenv:Envelope>}    System.ServiceModel.Channels.Message {System.ServiceModel.Channels.BufferedMessage}

 

Thanks! 

 

Terry

TerryLuschenTerryLuschen

After adding in a Soap header with the SessionID I am still getting a message that:  INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session

 

I was able to add to add the message header for sessionID with code like this...

 

System.ServiceModel.Channels.AddressHeader addressHeader1 =
                   System.ServiceModel.Channels.AddressHeader.CreateAddressHeader( "sessionId", "",  myArg.Result.sessionId);
System.ServiceModel.Channels.AddressHeader[] addressHeaders1 = new System.ServiceModel.Channels.AddressHeader[1] { addressHeader1};
Uri myUri = new Uri(myArg.Result.serverUrl);
 System.ServiceModel.EndpointAddress myEndPoint = new System.ServiceModel.EndpointAddress(myUri, addressHeaders1);

 

Here is my Request....

 

-        Request    {<?xml version="1.0" encoding="utf-16"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <sessionId>00DE0000000Hjbh!ARkAQJQX2UtqFTZKP24r7PTthlu6vwZR7JWJn5YLoRNKYAimRLZTNtIzrkwNzAabQgjkIeMkKf.mFbmsNDuZJJoiBvugyPYu</sessionId>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <retrieve xmlns="urn:enterprise.soap.sforce.com">
      <fieldList>Name</fieldList>
      <sObjectType>Game__c</sObjectType>
      <ids>
        <string>a00E0000000iaEcIAI</string>
      </ids>
    </retrieve>
  </s:Body>
</s:Envelope>}    System.ServiceModel.Channels.Message {System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage}

 

Here is the reply with the error...

 

+        Reply    {<?xml version="1.0" encoding="utf-16"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sf="urn:fault.enterprise.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" />
  <soapenv:Body>
    <soapenv:Fault>
      <faultcode>sf:INVALID_SESSION_ID</faultcode>
      <faultstring>INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session</faultstring>
      <detail>
        <sf:UnexpectedErrorFault xsi:type="sf:UnexpectedErrorFault">
          <sf:exceptionCode>INVALID_SESSION_ID</sf:exceptionCode>
          <sf:exceptionMessage>Invalid Session ID found in SessionHeader: Illegal Session</sf:exceptionMessage>
        </sf:UnexpectedErrorFault>
      </detail>
    </soapenv:Fault>
  </soapenv:Body>
</soapenv:Envelope>}    System.ServiceModel.Channels.Message {System.ServiceModel.Channels.BufferedMessage}

 

Help?  Is my SessionID not formatted properly?

 

Does it have to look like this instead?

//<soapenv:Header>
            //    <urn:SessionHeader>
            //        <urn:sessionId>xxxxxx</urn:sessionId>
            //    </urn:SessionHeader>

 

Thanks!

SuperfellSuperfell

Yes, your session header is wrong, and it should be as you state at the end of the post.

TerryLuschenTerryLuschen

I really appreciate your help Simon!

 

I can now make my request look a lot better by formatting an object instead of a string, but I stil get the same 'Invalid Session ID' error.

 

Here is my new code:

SessionHeader myHeader = new SessionHeader();
            myHeader.sessionId = myArg.Result.sessionId;
            System.ServiceModel.Channels.AddressHeader addressHeader1 =
                   System.ServiceModel.Channels.AddressHeader.CreateAddressHeader("SessionHeader", "", myHeader);

 

Here is my new request object:

+        Request    {<?xml version="1.0" encoding="utf-16"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <SessionHeader xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <sessionId xmlns="http://schemas.datacontract.org/2004/07/YouTubeSearch">00DE0000000Hjbh!ARkAQNp45M8a5FG3x.SoookJIuDbIxQzUcFECgbJ8MFsa3ZaU417HQXHWtWYNrtoDjhbP9qojWDwxpQ45Zon.L4_Xw1FHTd7</sessionId>
    </SessionHeader>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <retrieve xmlns="urn:enterprise.soap.sforce.com">
      <fieldList>Name</fieldList>
      <sObjectType>Game__c</sObjectType>
      <ids>
        <string>a00E0000000iaEcIAI</string>
      </ids>
    </retrieve>
  </s:Body>
</s:Envelope>}    System.ServiceModel.Channels.Message {System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage}

 

Do I have to some how get the urn: in front of the SessionHeader and SessionId values?

Is the "xmlns" causing a problem?

 

Thanks!

 

Terry

SuperfellSuperfell

The SessionHeader and sessionId elements are both in the wrong namespace, the exact prefix doesn't matter, but the URI does, it needs to look something like

 

 

    <SessionHeader xmlns"urn:enterprise.soap.sforce.com">
      <sessionId>some sid</sessionId>
    </SessionHeader>

 or

 

    <p:SessionHeader xmlns:p="urn:enterprise.soap.sforce.com">
      <p:sessionId>some sid</sessionId>
    </p:SessionHeader>

 

 

 

TerryLuschenTerryLuschen

I have been able to manipulate the SessionHeader xmlns values with the DataContract and DataMember values from System.Runtime.Serialization.

I'm sorry to say this, but..

Here is my new error:

<faultcode>soapenv:Client</faultcode>
      <faultstring>Unexpected element {urn:enterprise.soap.sforce.com}string during simple type deserialization</faultstring>

I'm pretty sure this error is referring to the "urn:enterprise.." after the <retrieve.
I can tell this because if I change the urn:enterprise in the SessionHeader line to something random I still
 get the same error.

My Request:


+        Request    {<?xml version="1.0" encoding="utf-16"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <SessionHeader xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:enterprise.soap.sforce.com">
      <sessionId xmlns="">00DE0000000Hjbh!ARkAQB6ICOrIIDensjf47Ek2KMngWY0OUeVLB0CKYpPU.AToXLPw_5ZTA6gWCuCLhpMi5uBbvY7.QPk4tAHxw00bZyhmNG2s</sessionId>
    </SessionHeader>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <retrieve xmlns="urn:enterprise.soap.sforce.com">
      <fieldList>Name</fieldList>
      <sObjectType>Game__c</sObjectType>
      <ids>
        <string>a00E0000000iaEcIAI</string>
      </ids>
    </retrieve>
  </s:Body>
</s:Envelope>}    System.ServiceModel.Channels.Message {System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage}

My Reply:


+        Reply    {<?xml version="1.0" encoding="utf-16"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" />
  <soapenv:Body>
    <soapenv:Fault>
      <faultcode>soapenv:Client</faultcode>
      <faultstring>Unexpected element {urn:enterprise.soap.sforce.com}string during simple type deserialization</faultstring>
    </soapenv:Fault>
  </soapenv:Body>
</soapenv:Envelope>}    System.ServiceModel.Channels.Message {System.ServiceModel.Channels.BufferedMessage}

I hope somebody else will learn from my pain.  :)


Thanks Again!

 

Terry Luschen

SuperfellSuperfell

Its not the namespace in retreive (which is correct), its this part

 

      <ids>
        <string>a00E0000000iaEcIAI</string>
      </ids>

 

it should be

 

      <ids>a00E0000000iaEcIAI</ids>

 

Have you thought of using the REST API instead ?

This was selected as the best answer
TerryLuschenTerryLuschen

Simon,

 

I ( we ) got it!

 

Thank you for all your help!! I have learned a ton.

 

I switched to using the queryAsync to work around the problem with the <ids> not being on the same line.   If the 'MessageHeaderArrayAttribute' were available in the Windows Phone .NET environment I would have been able to make it work.  But anyway, it works now!

 

string qry;
            qry = @"SELECT ID, Name, Phone, Email, Department FROM User";

            myRetrieveClient.queryCompleted += new EventHandler<SForceServiceE.queryCompletedEventArgs>(soapQueryCompleted2);
            myRetrieveClient.queryAsync(qry, myArg.UserState);

 

Thanks!

 

Terry Luschen

zaheerzaheer

Can you please tell me How did you add salesforce API in windows phone. I am working on this and I am unable to even add this.

 

Thanks