WEBfactory 2010

Using and handling the login programmatically with client SDK

Abstract

Check out this article and learn how to use and handle programmatically the WEBfactory 2010 login with client SDK.

The following article explains how to use and handle the login procedure using the WEBfactory client SDK. 

To run the example solution provided in the link above, WEBfactory 2010 must be installed on the local machine. If WEBfactory 2010 is not installed, the project references must be updated with the path to the Silverlight controls on the local machine.

Login control breakdown

The code source of the login control will follow the next procedure:

  1. Initializing variables and creating a connector, specifying that the connector is in design mode or not. For this particular case, the connector is not in design mode. Attaching the connector to the UserContextChanged event. The UserContextChanged event is thrown when the login or the logout has happened in WEBfactory server.

    public LoginUserControl() //The constructor	
    {
    	InitializeComponent(); // Required to initialize variables
    	connector = new WFConnector(false); //Creating the new connector
    	connector.UserContextChanged += connector_UserContextChanged; //Attaching the connector to the UserContextChanged event 
    }

    The Dispose() method is called.

    public void Dispose() //The Dispose method
    {
    	if (connector != null) //Checking if the connector is null
    	{
    		connector.UserContextChanged -= connector_UserContextChanged;
    		connector.Dispose(); //Disposing the connector
    	}
    }

    WEBfactory encourages any developer do use the Dispose() method in every disposable WEBfactory component to avoid memory leaks.

  2. Handling event that will be triggered when the login button (uxLoginButton in the provided example) is clicked and the event triggered when the logout button (uxLogoutButton in the provided example) is clicked.

    The uxLoginButton_Click event handler will call the Login() method, passing as parameters the uxUsernameTextBox.Text (username text), uxPasswordTextBox.Password (the password text) and the uxIsDomainCheckBox.IsChecked.Value (if the user is a domain user, this option will be true).

    The uxLogoutButton_Click event handler will call the Logout() method, passing no parameters.

    private void uxLoginButton_Click(object sender, RoutedEventArgs e) //The uxLoginButton_Click event handler
    {
    	Login(uxUsernameTextBox.Text, uxPasswordTextBox.Password, uxIsDomainCheckBox.IsChecked.Value);  
    	//When the login button uxLoginButton is clicked, the Login method is called	
    }
    private void uxLogoutButton_Click(object sender, RoutedEventArgs e) //The uxLogoutButton_Click event handler
    {
    	Logout(); //Calling the Logout() method
    }
  3. Attempting to start the login process using the Login() method.

    The Login() method will try to start the login process, calling the TryLogin() method, passing the attributes from step 2 (userName, password and isDomainUser ). If any exception occurs and the attempt to start the login process fails, the exception message will be displayed.

    private void Login(string userName, string password, bool isDomainUser)
    {
    	try //The attempt to start the login process, using a try-catch block
    	{
    		TryLogin( //Trying to start the login with the defined parameters
    			userName,
    			password,
    			isDomainUser);
    	}
    	catch (Exception ex) //In case of attempt failure, the exception will not crash the application
    	{
    		MessageBox.Show(string.Format("{0} {1}", base.GetType().Name, ex.Message)); //Displaying the exception message	
    	}	
    }

    The TryLogin() method will call the LoginUser() method from WFConnector, the method that actually resolves the login. If no username is provided, the TryLogin() method will not call the LoginUser method.

    	private void TryLogin(string userName, string password, bool isDomainUser)
            {
                if (string.IsNullOrEmpty(userName)) return; //If the username is missing, the login process is not started
    
                connector.LoginUser( //The method from the connector that actually starts the login
                    userName,
                    password,
                    isDomainUser, 
                    OnLoginResultHandler); //The method that will check the result of the login attempt
            }

    Besides the three specified parameters, the LoginUser() method will pass another call-back method, OnLoginResultHandler, which will check the result of the login attempt:

    	private void OnLoginResultHandler(Exception error, int[] results)   //Checks if the login result is valid/processed
            {
                HandleLoginAttemptResult(error, results); //Handles the result attempt
            }

    If the login attempt result is valid, the OnLoginResultHandler method will start handling the result by calling the HandleLoginAttemptResult method:

    	private void HandleLoginAttemptResult(Exception error, int[] results)
            {
                var errorCode = results == null ? 0 : results.FirstOrDefault(); 
    //If the error code received from the method is null or is and array with a single element which is 0, then the attempt was successful
    
                if (IsSuccesfull(error, results))
                {
                    //The login attempt was successfully initialized
                }
                else
                {
                    HandleLoginAttemptFailure(error, errorCode); //If the login attempt was not successfully initialized, this method will handle the failure cause
                }
            }
    	private bool IsSuccesfull(Exception error, IEnumerable<int> results) //Checking if the login is successfull
            {
                var errorCode = results == null ? 0 : results.FirstOrDefault();
    
                return error == null && (errorCode == null || errorCode == 0);
            }

    If the above method returns true, we know that the login attempt was successful. The actual login procedures are made in the WEBfactory server.

  4. If the login attempt is successful, an event will notify UserContextChanged callback that the login (or logout) has be made in the WEBfactory server.

    When the connector_UserContextChanged is notified that the login is successful, it will set the userName from the server in the local variable currentUser .

    	private void connector_UserContextChanged(string userName) //An event will notify if login or logout was made in the server
            {
                currentUser = userName; //Setting the userName in the currentUser local variable
    
                HandleUserContextChangedLogout(); //Handles the logout
            }
  5. If the login attempt is unsuccessful, the HandleLoginAttemptFailure() method will handle the failure.

    	private void HandleLoginAttemptFailure(Exception error, int errorCode)
            {
                string errorMessage = error != null
                                          ? error.Message //If there is an error in communicating with the server, the error message will be displayed
                                          : GetTextFromErrorCode(errorCode); //If there was no error in communicating with the server, it will display the text for an error code
    
                MessageBox.Show(errorMessage);
            }

    The GetTextFromErrorCode() method will get the appropriate error code message in case the error is other than a server communication error.

    	private string GetTextFromErrorCode(int errorCode)
            {
                if (errorCode == null) return "Login attempt failed";
    
                string translation = null;
    
                switch (errorCode)
                {
                    case -404:
                        translation = "Login failed - cannot obtain current logged in user name";
                        break;
    		case -4082:
                        translation = "Login failed - the number of failed logins exceeded. Username blocked.";
                        break;
    		case -4086:
                        translation = "Login failed - invalid command syntax";
                        break;
    
                    case -4087:
                        translation = "Login failed - expired password";
                        break;
    
                    case -4089:
                        translation = "Login failed - internal server error"; 
                        break;
    
                    case -4090:
                        translation = "Login failed - max count reached"; 
                        break;
    
                    case -4091:
                        translation = "Login failed - invalid username or password";
                        break;
    
                    case -4092:
                        translation = "Login failed - already logged on"; 
                        break;
    
                    case -4094:
                        translation = "Login failed - invalid username or password";
                        break;
    
                    default:
                        translation = "Login attempt failed"; 
                        break;
                }
    
                return translation;
            }

    Open the article here for more information of error codes.

  6. The logout event is triggered by the uxLogoutButton_Click event handler, which will call the Logout() method.

    	private void uxLogoutButton_Click(object sender, RoutedEventArgs e)
            {
                Logout();
            }

    The logout() method calls the connector method that will execute the actual logout procedure, and will use a try-catch block in order to avoid crashes and display the error message in case an error occurs.

    	private void Logout()
            {
                try
                {
                    connector.LogoutUser(); //Calls the method from the connector that will execute the logout procedure
                }
                catch (Exception ex) 
                {
                    MessageBox.Show(string.Format("{0} {1}", base.GetType().Name, ex.Message)); //In case of logout failure, the error message will be displayed
                }
            }

    If the logout procedure is successful, the server will notify the UserContextChanged event handler that will call the HandleUserContextChangedLogout() method to handle the logout.

    	private void HandleUserContextChangedLogout() //Handles the logout
            {
                if (!string.IsNullOrEmpty(currentUser)) return;
    
                MessageBox.Show("Logout successfull");
            }