Tuesday, 20 August 2013

The most simple c# event ever!

How to simply raise a basic event and subscribe to it really caused confusion for me. Even the most simplest of examples didn't seem all that easy to understand. Even now I don't pretend to understand them, but in my own limited way I can use them. 

For a long time I misunderstood what an event was capable of, thinking you could simply subscribe to a random event anywhere in your code and it would magically work. Of course I realise this is not the case. 

So, to my simplest of events:

I wish to raise an event once something has completed a task, normally once a background thread has finished processing. 

First I set-up the event and delegate which will be used for subscription and raising the event in the Class which is performing my work. 


public delegate void GetUsersWorkerIsComplete(object sender, EventArgs e, string myString);
public event GetUsersWorkerIsComplete UsersReturned;

Then I call the event, checking first that there is a subscriber to the event. 


if(UsersReturned != null)
  { 
     UsersReturned(this, EventArgs.Empty, returnlistOfUsers);
  }

Finally in the class which is calling the method under which this work is performed, I subscribe to the event and handle it. 


void GetUser()
 {
    var users = new Classes.Server.Users.GetLocalDetails();

    users.UsersReturned += Users_UsersReturned; //My event subscriber

    users.AllUsers(); //The method I'm calling which eventually calls the event.
}
//My Event Handler
void Users_UsersReturned(object sender, EventArgs e, string myString)
{
    string myEventString = myString;
}

Monday, 19 August 2013

Dispatching an action to the UI Thead



When working with multi-threaded applications you often need to poke information back to the main (GUI) thread. 

It could be to update the status bar with information during an asynchronous task or notify the user in a more direct way. 

There are many ways of doing this, but I keep it as simple as possible by Invoking a Dispatcher

Invoking the Dispatcher gets the threading dispatcher of the object you are about to call an action on and subsequently calls it on that thread. 
In order words, it finds the appropriate thread and calls the method on it. 

The Set-up


In this example I have a login box that I want the user to populate with a valid username and password. Once the user clicks 'OK' my application will create a background thread to validate the login. If this takes too long, the user may believe the login has failed or crashed, so we present a Busy indicator with a status update. 

I want to update the busy indicator with the progress of the authentication, but as the authentication class is executed in a separate thread, I must use my Dispatcher. 

First, I must make my Window class accessible:



public partial class Userlogin
{
   public static Userlogin LoginHandle;
       public Userlogin()
       {
        InitializeComponent();
        LoginHandle = this; 
       }
}

This allows for my Window to be called from elsewhere in the application. 

I also have a control in my XAML called Busy

<telerik:RadBusyIndicator Name="Busy" IsBusy="False" HorizontalAlignment="Left" Height="124" Margin="10,56,0,0" VerticalAlignment="Top" Width="334"/>


From anywhere in my application I can now call 'Busy', or any other UI element. 

Window.Userlogin.LoginHandle.Busy.IsBusy = true;


However this does not allow me to do this from another thread, this is where the Dispatcher comes in. 


Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
new Action(() =>
Window.Userlogin.LoginHandle.Busy.BusyContent = "Validating Credentials"));


BeginInvoke calls the delegate on the thread it the dispatcher is associated with. 

Very handy.

Sunday, 18 August 2013

Communicate with Active Directory via LDAP

Having written a natty local authentication system for an application I wanted to expand it further by authenticating users against a domain too, as an option. 

I have a test domain controller on another machine, but my development machine is not joined to that domain. 

Reading a few stack overflow posts it seemed the best method of communicating with AD is via System.DirectoryServices.AccountManagement . This under the hood uses the older, domain communicate API but makes it all a little bit more accessible to idiots newbies like me. 

It's relatively simple:

Set-up your context

var ctx = 
new PrincipalContext(ContextType.Domain, "server", "DC=doom,DC=home", 
ContextOptions.SimpleBind, username,password);



I discovered 'ContextOptions' very important in my testing as the default bind option didn't work for me. 

Validate your credentials


var validCredentials = 
ctx.ValidateCredentials(username, password, ContextOptions.SimpleBind);












This is how I determine if the user has passed me valid credentials

Pull out the user details from the AD


var user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, username);






However, the above will not work if your development machine is not joined to the domain. The workaround is to open up your network settings and use the domain server as your only DNS server, otherwise your application will not be able to locate the domain and associated services to complete the request. 




Finally, you're really going to want to put all this on a separate thread. LDAP queries take an age!