One of the enhancements that the HR team has been asking for since I first launched this is the ability to attach some of the files that applicants send to the applicants once they are entered into the system.  This way, when looking through applicants anyone can easily view their resume, cover letter, or project (yes, sometimes there are projects!) as well as add a rating value to the project.  Seeing as we have a RadUpload control for Silverlight, I figured this would be a great opportunity to get that running in the application, especially since we have the new RadUploadDropPanel that makes it even easier to get files uploaded in your applications.

Since it always provides for the most *interesting* approach to things, we're first going to implement this in the MVVM version of the application and then we'll move over to the regular code-behind/event driven version for comparison sakes (that comes in the next post). 

<!-- Note - I know from a previous comment on the last post someone asked for the full source code, but that isn't quite available yet.  I'm doing a significant amount of refactoring and tweaking to make this app more streamlined and additionally to improve the user experience for my friends in HR, so putting up the code now would be like you walking into the repair shop when they have your engine in pieces 15 feet from your car.  Trust me, it'll be worth it. :) -->

The first thing I realized in this quest is that I'd need to create folders to store these files, and to avoid any overwriting of similarly named files (you have no idea how many people send in CoverLetter.docx), we want folders unique to each applicant.  The first try at this was to simply use the generated ApplicantID when creating an applicant, but something about that didn't sit quite right so instead we modified the model a tiny bit and added ApplicantGUID and a few other fields to cover things we like to look at:

Applicant Model Picture

With that set, we need to ensure that we are actually adding and using the new GUID for our applicants that our WCF RIA Service can use for creating user folders.  Therefore our refactored AddApplicant method on ApplicantViewModel.cs looks like this:

public void AddCompleteEventHandler(Applicant anApplicant)
{
    AddApplicant(anApplicant);
    this.MakeMeActive(this.regionManager, "MainRegion", "ApplicantsView");
}
public void AddCompleteNoCloseEventHandler(Applicant anApplicant)
{
    AddApplicant(anApplicant);
}
public void AddApplicant(Applicant anApplicant)
{
    if (anApplicant == null)
    {
        // do nothing, new applicant add cancelled
    }
    else
    {
        // This is necessary for applicant file uploads, since we need a unique directory per applicant
        anApplicant.ApplicantGUID = Guid.NewGuid();
        this.context.Applicants.Add(anApplicant);
        this.context.SubmitChanges((s) =>
        {
            // First we notify the user that the applicant was added successfully
            eventAggregator.GetEvent<NotifyUserEvent>().Publish("Applicant added successfully");
            ActionHistory myAction = new ActionHistory();
            myAction.ApplicantID = anApplicant.ApplicantID;
            myAction.PostingID = anApplicant.PostingID;
            myAction.Description = String.Format("New applicant {0} {1} has been added for position {2} by {3}", anApplicant.FirstName, anApplicant.LastName, anApplicant.PostingID.ToString(), "default user");
            myAction.TimeStamp = DateTime.Now;
            eventAggregator.GetEvent<AddActionEvent>().Publish(myAction);
        }
        , null);
    }
}

The astute reader will also notice that previously there was only AddCompleteEventHandler - to stick with the logic I already have, which I kind of like, I'm keeping the logic but moving it to an AddApplicant method and letting the event handlers (which are using the EventManager from Prism for some loose-coupling action) call this and additionally change the active view if necessary. 

Getting back on track, having that GUID allows me to then create a unique folder for every new applicant to store their files.  We take care of this in the WCF RIA Service itself when we perform the auto-magically created Insert operation.  After the generated code handles the actual operation, we add this little bit to create a directory based on the application directory and ApplicantGUID as well as set a FileSystemAccessRule so that these files can be accessed.  For the demo I am using Everyone, but this is where you would give people on your ActiveDirectory, etc., access:

// Create our strings, makes it easier to use them down the line
string baseDirectory = "C:/Projects/VS2010/Projects/TelerikRecruiterSilverlight/Recruiter/Recruit/Recruit.Web/";
string subDirectory = "HR/applicants/" + applicant.ApplicantGUID.ToString();
// Create a DirectoryInfo object for our base directory, allowing us to create a subdirectory
DirectoryInfo di = new DirectoryInfo(baseDirectory);                
di.CreateSubdirectory(subDirectory);
// Create a new DirectoryInfo based on our subdirectory, then 'Allow' 'Everyone' access to 'Read' files there
DirectoryInfo subDI = new DirectoryInfo(baseDirectory + subDirectory);
DirectorySecurity subDISecurity = subDI.GetAccessControl();
subDISecurity.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.Read, AccessControlType.Allow));
// Set this security access to our subdirectory, so we can then read files (aka, click a link to download/view)
subDI.SetAccessControl(subDISecurity);

So we've got an updated model, updated methods for adding an applicant, and the ability to create a directory based on all this goodness that we can utilize with RadUpload to attach files to applicants.  Stay tuned for tomorrow, when we actually implement RadUpload in the MVVM application through a clever use of attached behaviors.


About the Author

Evan Hutnick

works as a Developer Evangelist for Telerik specializing in Silverlight and WPF in addition to being a Microsoft MVP for Silverlight. After years as a development enthusiast in .Net technologies, he has been able to excel in XAML development helping to provide samples and expertise in these cutting edge technologies. You can find him on Twitter @EvanHutnick.

Related Posts

Comments