Last week, i discovered a nice things about the connection to the CRM and the console application.
We have some jobs running on azure continuously, and we discovered that after 8hours, if there was no query to the CRM, the token was not valid anymore.
Usualy when I create console application, it's for fixing / testing stuff within an hour, so obviously I couldn't figure this out before.
The trick here is to make sure that you either :
- have a Request done to the server before the next 8 hours.
- you decide to renew the Token every X hours (I went this way).
Good to know :
This token is not generated when you create your connection to the CRM but when you perform your first call to it by using a Retrieve / RetrieveMultiple or whatever action you want to perform.
Then a Token is retrieved from the server and this token last 8 hours.
Each time you perform a request, this will either update the "end" time of your token or generate a new one if none was defined before. BUT if you had one and it expired, you are done with this session, you have to restart your app.
Our CRM friend is sometimes not totally clear about the root cause when you have exception.
To figure out the issue, I had this two kind of errors :
"OrganizationServiceProxy => Cannot access a disposed object" and "An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail"
Problem here is when you try to reproduce the issue on your laptop, since you restart the application, you won't see it ...
Tips to force the reproducing : launch your application, cut all internet access and you will have the exception.
If now we give a closer look to the exception :
You can see that the property "token" has two interesting information : "validFrom" and "validTo", and this is exactly 8 hours.
As said above, I decided to be sure that my app will be able to run everytime so my process was to "force" the renewing of the token every 7 hours.
To do so, I'm using a simple Timer();
public void CRMRenewToken()
{
this.timer = new Timer();
this.timer.Interval = 1000 * 60 * 60;
this.timer.Elapsed += Timer_Elapsed;
this.timer.Enabled = true;
this.timer.AutoReset = true;
this.timer.Start();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
Trace.TraceInformation($"timer is finished calling the reconnect function (now expire at :{this.serviceproxy.SecurityTokenResponse.Response.Lifetime.Expires.Value.ToUniversalTime()})");
this.serviceproxy.Authenticate();
}
The first method trigger a new Timer which will restart every 7hours and call the "Timer_Elapsed" event.
And in the second method, we simply retrieve our OrganizationServiceProxy to call the Authenticate() method.
/!\ The Authenticate() method is not available on the IOrganizationService objects.
Now you are safe and can let you application run for years !
Happy CRM'ing,
Clément