Saturday, 6 February 2010

Silverlight Multi File Upload control

I have been making some updates to my multisite content management system to enhance the user experience.
I found http://slfileupload.codeplex.com/ by Michiel Post to be excellent.

I found its one limitation was that I was unable to get the name of the files uploaded within the javascript event handler, that was until I made some changes to the code. I have submitted the changed to be included so hopefully you'll not need to make the changes, but until then, here they are.


I created a file called FileUploadedEventArgs.cs

namespace mpost.SilverlightMultiFileUpload.Classes
{
    [ScriptableType]
    public class FileUploadedEventArgs : EventArgs
    {
        [ScriptableMember()]
        public string FileName { get; set; }
        public double FileSize {get; set;}

        public FileUploadedEventArgs(string fileName, double fileSize)
        {
            FileName = fileName;
            FileSize = fileSize;
        }
    }
}


and changed FileCollection.cs line 276
SingleFileUploadFinished(this, null);
to
SingleFileUploadFinished(this, new FileUploadedEventArgs(file.FileName, file.FileSize)); 


An example of the javascript to access the data.

        function SingleFileFinished(sender, args) {
            alert(args.FileName);
            alert(args.FileSize);
        }

 

Friday, 22 January 2010

Asp.net MVC with Entity Framework Architecture

Introduction

As I have a strong interest in software architecture I will be giving an overview of the architecture I have used to create my multisite content management system, which will be open to your suggestions for improvement. I have aimed to create a loosely coupled – highly coherent architecture to keep the application maintainable and as extensible as possible as I plan to add new features as an when they are needed.

Technologies used

  • Unity application block for dependency injection
  • Asp.net MVC
  • Entity Framework
  • JQuery
Architecture

The architecture consist of a Repository layer a Services layer and Asp.net MVC for the presentation.

The repository layer is responsible for getting objects in and out of the datastore which are to be used by the service layer. The service layer is responsible for applying the business rules and providing the presentation with required services.

I have tried to show the basic overview below. I will go in to more detail a bit later on, but basically the services for example have a reference to the IGalleryRepository and Unity takes care of creating a new instance of the EntityFrameworkGalleryRepository.




To keep the Entities generated by the Entity Framework out of the rest of my application and keep the dependency on the Entity Framework contained to the EntityFrameworkRepository that implements the repository interface, the entities are mapped to POCOs. This will enable me to switch to Linq-Sql or some other data storage strategy will a lot less hassle.

public TextContentRepository.Concrete.TextContent GetTextContent(int textContentId, Guid applicationId)
{
        using (entities = GetContext())
       {

                JJCore.TextContent textContent = entities.TextContent
                                                                                     .Include("ApplicationPage")
                                                                                     .FirstOrDefault(
                                                                                           t => t.TextContentId   == textContentId 
                                                                                           && 
                                                                                           t.ApplicationPage.Application.Id ==
                                                                                                                                      applicationId);

               JJRepositories.TextContentRepository.Concrete.TextContent toReturn =
                        new  JJRepositories.TextContentRepository.Concrete.TextContent(textContent);

              return toReturn;
        }
}


Above is an example of using the entity framework while keeping the rest of the application isolated from it.

I have created a POCO with a constructor that takes the entity as an argument but I will be improving this by creating a Mapper class, by using AutoMapper or by switching to Entity Framework 4 to make use of POCOs.

I would also like to remove the magic string for the includes in the near future too.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Application application)
{
        application.Validate(ModelState);

        if (!ModelState.IsValid)
           return View(application);

        applicationService.SaveApplication(application);

        return RedirectTo

       Action("Index");
}

The above is an Action on the SitesController. It has one specific responsibility.
Pass the application to be saved if it is valid.

I have not gone in to much detail on the MVC part of the implementation, I'll save that for another post. I have ensured that I am always programming to interfaces to allow for easier unit tests (another post) and dependency injection.
I hope I managed to describe the architecture and I welcome you comments and suggestions for improvement.

Monday, 23 November 2009

Use Linq to get selected Items on a ListControl

Very quick post, if you would like to get all ListItems from a ListControl where Selected == true you can do this with Linq.

lcListControl.Items.Cast().Where(i => i.Selected)

you can even just get the selected values

clRoomTypeNights.Items.Cast().Where(i => i.Selected).select(li => li.Value)

Monday, 2 November 2009

Screen scraping Job Centre Plus

You would have thought the government would be doing everything they can to get people in to work, wouldn't you?

I am working on a project which requires local job centres and job to be displayed to the user. No problem I thought, I'll just head over to the Job Centre Plus website and find out about the API they offer, or in this case don't.

It seems the only way I was going to do this is to screen scrape for the information I require, which it turns out wasn't as difficult as it sounds. Getting the local job centres was quiet easy, just make a request to the correct url with some post variables and hey presto I got the result I required, searching for jobs was not that simple, more on this later.

string url = "http://www.jobcentreplus.gov.uk/JCP/Aboutus/Ouroffices/Search/LocalOfficeSearch.aspx";

Dictionary postVariables = new Dictionary();
postVariables.Add("Action","SearchOffices");
postVariables.Add("Type", "0");
postVariables.Add("TypeName", "");
postVariables.Add("OfficeSearchCriteria", postcode);
postVariables.Add("BeginSearch", "Find+Office");

With the result from this request I started to use Regex to find the data I needed, as the result was not valid Xhtml I couldn't just parse the xml as I had planned. I stumbled on the HtmlAgilityPack (http://htmlagilitypack.codeplex.com/) and with a little XPath the job was a good un'.

Searching for the jobs was a different kettle of fish, for a start it seems to require a sessionId in the query string which makes sending a link to the job to someone else quiet difficult and makes my job a little harder.

I first had to make a request to the search page to take the viewstate data and edit it to match the terms I wished to search for and then make a request to the result page.

string post = string.Format("__VIEWSTATE{0}&__EVENTTARGET=uctlHCCDialogue%3AbtnSearch&uctlHCCDialogue%3AtxtUserInput=all+jobs+in+{1}&uctlHCCDialogue%3AbtnSearch=Search", viewState, postcode.Replace(" ", "+"));

Regex exp = new Regex( @"\?sessionId=[0-9a-zA-Z-]*&pid=[0-9]*", RegexOptions.IgnoreCase);

I've still got work to do, I need to be able to make a request after the session has expired, this needs to be seamless to the user.

Check back soon for an update and check my website for more information on the project or if you require development work jamie jones freelance web developer