+ Start a Discussion
cocasthefrogcocasthefrog 

Using SessionID to Login in C#

I have a Web Integration Link in SalesForce that redirects to a page in my server. I want to login and get data from salesforce without ask the password again...using the login in salesforce.

It's possible? My language is c#

Can you help me...it's important!

 

 

 

fouloxfoulox
Once you have the sessionID you don't need to login, just set the sessionID and get the data.
mceruttimcerutti
I have done this.  You pass the session_id on the querystring and then use it to make the API calls.  Technically you should perform a login call with an id in order to get the URL for the API, but I have seen several posts where people are hard-coding the URL.
cocasthefrogcocasthefrog
Just set the sessionID and get data?... do you have samples of that
cocasthefrogcocasthefrog
Can you show me an example of that? I've tried but i can't do that
mceruttimcerutti

I don't have a simple example.  My original code was 2.0 and looked something like this:

private sfconnector sForce = new sfconnector();
object[] ret;
ret = (object[])sForce.login(APIVersion, _userName, _password, _useSecureURL, _applicationName);

XmlElement xElement = (XmlElement)ret[0];
sForce.headerStructValue = new headerStruct();
sForce.headerStructValue.session_id = xElement.SelectSingleNode("/valueMap/session_id").InnerText;
sForce.headerStructValue.version = APIVersion;
sForce.Url = xElement.SelectSingleNode("/valueMap/server_url").InnerText;

sForce.headerStructValue.session_id  = Request.QueryString["sid"].ToString();

Here is the converted 2.5 code (untested):

private SforceService sForce25 = new SforceService();
LoginResult ret;
ret = sForce25.login(_userName, _password);

sForce25.SessionHeaderValue = new SessionHeader();
sForce25.SessionHeaderValue.sessionId = ret.sessionId;
sForce25.Url = ret.serverUrl;
sForce25.SessionHeaderValue.sessionId = Request.QueryString["sid"].ToString();

The WIL link has this parm: sid={!User_Session_ID}

Hope this helps.

cocasthefrogcocasthefrog

I do what you say and the application return me an error:

My username and password are in blank...

Note: I don't want to know the password!just login in salesforce using another way

This is the error:

 

username or password not valid

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.Services.Protocols.SoapException: username or password not valid

Source Error:

Line 42:         [return: System.Xml.Serialization.XmlElementAttribute("result")]
Line 43:         public LoginResult login(string username, string password) {
Line 44:             object[] results = this.Invoke("login", new object[] {
Line 45:                         username,
Line 46:                         password});

DevAngelDevAngel

Hi cocasthefrog,

If you have a valid sessionID as from a web integration link, you do not need to login.  So, if you look at the samples, directly after logging in the samples set the session id on the session header value, reset the url to the correct app server instance and then issue the next method call.  When you have the session id, you can simply skip the login call.  The login call returns a server url, session id and user id.  You con obtain the user id, if required by calling the getUserInfo method.  The session id is passed by the web integration link as merged field.  Likewise, you can have the web integration link pass the correct app server instance.

The login method is not defined as having a session header and user name and password are required.  This is why your call is failing.  Skip the login if you have the session id and get the other values that are returned from the login by using the appropriate merge fields when setting up the web integration link.

Cheers

cocasthefrogcocasthefrog

Thanks! It works...

This is the code

sforce.SforceService sForce25 = new sforce.SforceService();

sForce25.SessionHeaderValue = new SessionHeader();

sForce25.SessionHeaderValue.sessionId = Request.QueryString["sid"].ToString();

sForce25.Url = Request.QueryString["srvurl"].ToString();

// Set the query options (Optional; default batch size is 2000)

sForce25.QueryOptionsValue = new QueryOptions();

sForce25.QueryOptionsValue.batchSize = 10;

sForce25.QueryOptionsValue.batchSizeSpecified = false;

// Invoke the query call and save the result in a QueryResult

QueryResult qr = sForce25.query("select FirstName, LastName,email from contact where email<>''");

// Get the returned records

sObject[] records = qr.records;

// Determine whether some records where returned

if (records.Length > 0)

{

xsd.Contacts ds = new xsd.Contacts();

for (int i=0;i<records.Length;i++)

{

Contact contact = (Contact)records[i];

ds.xsdContacts.AddxsdContactsRow(contact.FirstName,contact.LastName,contact.Email);

}

dgContacts.DataSource=ds;

Page.DataBind();

}

else

{

System.Diagnostics.Trace.WriteLine("no records matched criteria");

}

DevAngelDevAngel

Hi cocasthefrog,

Great!  Glad you got it working.  Couple of recommendations though.  In your code where you check to see that records has a length of greater than zero, I would instead use if (qr.size > 0).  The size parameter will return the full size of the returned data.  This is more a style issue than anything, so take it as such.  The other parameter on the query return is the done flag.  This flag indicates whether or not there is more data to be returned.  This can happen if the query results in a record set that is larger than the batch size specified in the query options header (default is 2000).  Depending on the ui, you may want to provide forward only paging, or perhaps, forward and backward paging. 

To do this you would set a reasonable query batch size of say 20.  Then, when the query returns you will have 20 records in the the records array and size may by 200.  A cursor like value is returned on the query when there are more values waiting to be returned called the query locator.  If the use would like the next 20 records, you could then make a call to the query more method passing the query locator.  The query result from query more is the same as from query.  By inspecting the done flag you will know whether or not to enable the "Next 20" link or whatever ui element tells the user that there are more.  In addition, you can display the total records  from the query using the size parameter. 

To enable backward paging you would have to cache the results on your server.

By the way, how did you create the xsd for Contacts?

cocasthefrogcocasthefrog

Hi DevAngel!

Thanks for your recommendations...

About the dataset, i did it manually. It's bad?

Ricardo,
Development Consultant

 

DevAngelDevAngel

Nope, just wanted to see if there was some new slick way of binding a wsdl to an xsd.  (Which would be nice given that .Net bases alot of wizards on xsd files.)

cocasthefrogcocasthefrog

There is an way...but it's not simple.

When i finish it i'll send it to you

Best Regards

 

mceruttimcerutti

I have 2 follow up questions.

1)  Did the previous SalesForce.com release have the URL as a parameter that could be passed through WIL?  I don't remember.

2)  If you don't login with your code, you are accessing the na1.salesforce.com server instead of the na1-api.salesforce.com server.  Does this matter?

 

DevAngelDevAngel

Hi mcerruti,

1. No.  You actually had to parse the referrer property of the document.

2. I don't think it matters right now, but that could change.  na1 is appropriate for API 2.0 and XML-RPC, but na1-api is preferred.  I

GL_NSGL_NS
Hi,
 
Please suggest how to open a Salesforce Page from C# page after getting SessionId using API.
 
Thanks...