Administration CreateUser method never returns (C#)
AnsweredI'm using the C# SDK to create rainbow users from my web app. I am logging in to Rainbow as an admin user after setting the App ID, app secret and hostname (sandbox). This is successful and then I move on to invoking the CreateUser method of the Administration object. What I am finding is that the users are getting created but the callback of the CreateUser method is never called, hence my web app sits idle and can never process the result of the request.
When I try to create a user with an email address that already exists, the behaviour is the same i.e. the callback is never invoked.
What could be the cause of this?
Example code:
var admin = rainbowApp.GetAdministration();
admin.CreateUser(userEmailAddress, userPassword, firstName, lastName, firstName, <company ID>, true, false, callback =>
{
if (callback.Result.Success)
{
// user created
contactId = callback.Data.Id;
jId = callback.Data.Jid_im;
}
else
{
if (callback.Result.Type == Rainbow.SdkError.SdkErrorType.IncorrectUse)
{
// Bad parameter(s) used
}
else
{
// Exception occurs
_rainbowApp.Logout();
// throw Exception
}
}
}
-
Hi,
The callback is always used on success or on error.
But as the callback signature suggests ( => "Action<SdkResult<Contact>>") the result is provided asyncronously so on a different thread.
I suppose you are using "contactId" and "Jid" incorrectly.
Could you share more source code to check this part ? -
Hi Christophe,
Thanks for your quick reply. 'contactId' and 'jId' are declared as local variables just before the call to CreateUser (see below). There are log messages in each branch of the callback but none of them ever appear. The code prior to the CreateUser call i.e. to log in as the admin user, is handled in the same was as CreateUser (as per the original code block above) and we always get a return from that callback.
var contactId = "";
var jId = ""; -
Login process is also asynchronous ...
1) Are you waiting the end of this aysnchronous call (i.e Login) before to continue ?
2) Did you respect this guide line: https://hub.openrainbow.com/#/documentation/doc/sdk/csharp/guides/030_connect_to_rainbow -
Did you find a solution of your problem ?
I share with you a little example . It demonstrates how to deal with aysnchronous methods in a synchromous way:
// Define ManualResetEvent object used in Login/Authentication process
private ManualResetEvent manualResetInitialization = new ManualResetEvent(false);
// Define another ManualResetEvent
private ManualResetEvent manualResetEvent = new ManualResetEvent(false);
// Define objects from the C# SDK
private Rainbow.Application rbApplication;
private Rainbow.Administration rbAdministration;
...
// Create SDK Objects
rbApplication = new Rainbow.Application("./");
rbAdministration = rbApplication.GetAdministration();
// Since we are doing provisioning we don't need to create a event pipe with the server
rbApplication.Restrictions.EventMode = Restrictions.SDKEventMode.NONE;
// Set a timeout to 10 seconds (it's huge - to ajoust according your environment)
rbApplication.SetTimeout(10000);
// Define application info and the server to use
rbApplication.SetApplicationInfo(ApplicationInfo.APP_ID, ApplicationInfo.APP_SECRET_KEY);
rbApplication.SetHostInfo(ApplicationInfo.HOST_NAME);
// We have to deal with several events of the SDK - it's the mandatory ones
rbApplication.ConnectionStateChanged += RbApplication_ConnectionStateChanged;
rbApplication.InitializationPerformed += RbApplication_InitializationPerformed;
...
// We login to RB
manualResetInitialization.Reset(); // We need to ensure to reset Manual Reset Event used in lgin / ahtnication process
// Start login (it's asynchronous)
rbApplication.Login(CompanyAdmin.Email, CompanyAdmin.Password, callback =>
{
if (!callback.Result.Success)
{
// Something wrong happened !
message = Util.SerializeSdkError(callback.Result);
}
});
// Login step is a asynchronous call - we need to wait event "InitializationPerformed" or "ConnectionStateChanged" ( with a disconnected state)
manualResetInitialization.WaitOne();
// Here we have finished authentication process
// If all has been done corretly:
// - the event "ConnectionStateChanged" has been raised twice: "connecting" then "connected"
// - the event "InitializationPerformed" has been raised once
if (!rbApplication.IsInitialized())
{
// Something wrong happened !
// TO MANAGE
}
// Create a user:
manualResetEvent.Reset();// We need to ensure to reset Manual Reset Event used
admin.CreateUser(userEmailAddress, userPassword, firstName, lastName, firstName, <company ID>, true, false, callback =>
{
if (!callback.Result.Success)
{
// Something wrong happened !
message = Util.SerializeSdkError(callback.Result);
}
// We inform the end of the CreateUser call
manualResetEvent.Set();
}
// We wait the end of the asynchronous call to CreateUser
manualResetEvent.WaitOne();
...
// Manage events "ConnectionStateChanged" and "InitializationPerformed"
private void RbApplication_InitializationPerformed(object sender, EventArgs e)
{
// The init has been done successfully - so we set "manualResetInitialization"
manualResetInitialization.Set();
}
private void RbApplication_ConnectionStateChanged(object sender, Rainbow.Events.ConnectionStateEventArgs e)
{
// If the connection is lost we need also to be informed - so we set "manualResetInitialization"
if (e.State == Rainbow.Model.ConnectionState.Disconnected)
manualResetInitialization.Set();
}
Please sign in to leave a comment.
Comments
5 comments