MVC: Handling file uploads

ASP.Net MVC has some great abstractions over HTTP and the various Http classes, but one area which is currently lacking is around processing of file uploads.  Uploaded files are (still) available on the Request.Files collection and some posts suggest that you should go down this route.  And for testing, Scott Hanselman has provided some (fairly scary) mocking code.

Now Phil Haack has suggested a few improvements on this, but it’s still not as easy to test as I’d like (I’m a lazy developer, really) – I like to avoid mocks when I can since they can easily obscure the intention of the test.  Fortunately MVC model binders came to my rescue here.  Note that my web UI is only ever submitting one file.

DTO class:

public class UploadedFile
{
    public int Length { get; set; }
    public string ContentType { get; set; }
    public string FileName { get; set; }
    public Stream Stream { get; set; }
}

Model binder:

public class FileUploadBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var postedFile = controllerContext.HttpContext.Request.Files[0];
        if (postedFile == null) return null;
        return new UploadedFile
                   {
                       Length = postedFile.ContentLength,
                       ContentType = postedFile.ContentType,
                       FileName = postedFile.FileName,
                       Stream = postedFile.InputStream
                   };
    }
}

Controller action method:

[HttpPost, Authorize]
public ActionResult PeformFullUpload(string dataSourceName, 
            [ModelBinder(typeof(FileUploadBinder))] UploadedFile uploadedFile)

Test code:

[When("the user submits a file")]
public void PerformFileUpload()
{
    var uploadedFile = new UploadedFile{ Stream = _memoryStream};
    _viewResult = _controller.PeformFullUpload(_dataSourceName, _uploadedFile) as ViewResult;
}

Now that’s how I like my tests.   Smile

December 16 2011

Scrum basics: Retrospectives

Retrospectives are a frequently overlooked aspect of scrum.  Perhaps this is because they are “non-functional”, in the sense that they don’t contribute directly to the output of the team.  I maintain, however, that good retrospectives are the key to a highly functioning team.

What is a retrospective?

A retrospective is a meeting where the team get to reflect on their current progress and process and decide how they can improve it.

What does it mean to improve progress and process?

It can mean absolutely anything … the team get to decide.  Remember that the purpose of scrum is to build a team that can smoothly and effectively deliver business value on a regular basis.  Anything which gets the team closer to this goal counts as an improvement.

It’s also important to point out that it is the team themselves which decide how they can improve.  People such as managers, IT directors, agile coaches and so on can make suggestions, but the team needs to take ownership of their process.  This is what it means for a team to be “self-organising” … an agile term which is bandied around a lot and is often misused.  The self-organisation of a scrum team is the main points of retrospectives.

What’s the difference between a good and a bad retrospective?

Retrospectives, like a lot of things in agile, need to be judged on their outputs.  A good retrospective will produce improvements that address important issues the team is facing.  A poor retrospective will skirt around issues and address unimportant issues.

For instance, suppose a team is consistently releasing buggy software.  A good retrospective will attempt to address the bugs, both in terms of fixing outstanding issues as well as attempting the underlying cause of the bugs.  A bad retrospective would focus on other incidental issues, e.g. variable names not adhering to the agreed coding standards.

Poor retrospectives can happen for a number of reasons:

  • they may be unaware of how well they are meeting business priorities (e.g. they don’t know that their software is buggy)
  • the team may be unaware of business priorities (e.g. they may mistakenly think that the bugs have a minor impact)
  • the team might not care about business priorities (e.g. they don’t care about their bugs)
  • the team may be unwilling to talk about their problems
  • the retrospective meeting might get side-tracked into addressing low priority issues
  • … and so on

Some of these issues can be addressed by ensuring good communication between the team and the business.  Some of these issues can be addressed by being careful with the retrospective meeting and its format.  The retrospective meeting can be structured in such a way that it encourages the team to discover, explore and address their big issues.

What’s the format for a retrospective meeting?

There is no single format retrospective meeting, and there is no retrospective format which is best.  Retrospectives can take many forms.  In fact, the format of retrospectives should be changed from time to time, as this encourages people to think about their situation in new ways.  A great resource for ideas about different formats is Agile Retrospectives, by Esther Derby and Diana Larsen.  There are many other resources available on the web too.

What would you suggest as a starting point?

Here is a retrospective which I often use for teams that are new to retrospectives.  Please do not use this without thinking about it and deciding how it will fit your team.

1. Introduction

Some sort of icebreaker activity.  For instance, everyone gives one word that for them sums up the sprint. It can be accompanied by explanation or not. Questions are not allowed at this point, since people should be thinking rather than talking.

2. Review previous actions

Look at the actions from the last retrospective.  Decide which were completed, perhaps discuss how effective they were and decide which, if any, the team should carry on with.

3. Gathering data

Everyone writes post-it notes to fall into 2 categories - "What went well" and "What went not so well". The team gets 10-15 min to write the notes and then individuals take it in turns to stick them up onto a whiteboard. As they stick up a note they should introduce it to the team "I wrote xxx because I felt that ...". Some questioning is allowed here, but the point is really just to gather information.  The use of post-it notes is a great equalizer and prevents dominant characters from dictating the course of the meeting.

4. Extracting insight

The facilitator then looks to group up the post-it notes into topics / themes. For instance, there may be a number that relate to daily standup meetings. Put these in a clump.

5. Decide on actions

The team now decide on actions to address the items that didn't work well. Start with the biggest clumps of post-its, since those are the issues that are causing the most pain. Generally it's not worth trying tackle all issues. When you have 4-8 actions then call time. There should be lots of discussion and brainstorming during this part of the retrospective. All actions should be specific and should have an owner who is prepared to take responsibility to see it implemented during the next sprint. If nobody volunteers to own an action, then throw it away because clearly nobody wants to see it implemented.

Actions which cannot be implemented by the team are not allowed, e.g. “business users must stop changing their mind”.  Actions which are vague (e.g. “improve communication”) need to be explored more and made specific.

October 21 2011

Getting the msdeploy.exe install path using powershell

 

I’ve been playing around with msdeploy and powershell lately, and one of the things I needed to find out is where the msdeploy.exe was located. After building a web deploy package, the associated batch file created by msdeploy uses a registry key to get the executables location.

Accessing the registry in powershell is super easy, so we may as well do the same thing. The key in question is: "HKLM:\SOFTWARE\Microsoft\IIS Extensions\MSDeploy" which we can access using a standard Get-ChildItem or gci for short.

image

I have both MSDeploy v1 and v2 installed, and it’s the latter one I want to get at so we can use a Select –Last 1 to choose it. We also want just the InstallPath property which is accessible via GetValue on the RegistryKey object.

image

Great! We can easily put this into a function and load it into our path using:

function Get-MSWebDeployInstallPath(){
     return (get-childitem "HKLM:\SOFTWARE\Microsoft\IIS Extensions\MSDeploy" | Select -last 1).GetValue("InstallPath")
}

function Load-Configuration
{
    $webDeploy = Get-MSWebDeployInstallPath
    $env:Path += (";" + $webDeploy)
}

You should be able to access msdeploy from your powershell script now…

What’s wrong with Windows?

Ever since the very early preview of Windows 8 much of the .NET developer community have been doing nothing but whingeing like a bunch old squaws along the lines of “Microsoft abandons .NET! and we will all have to program now in [javascript|HTML5|COM|C|C++]”, etc. The whingeing has been to a large extent fuelled by the cries of HTML/Javascript monkeys who had a field day at the expense of XAML/.NET developer: “Haha, all your time spent mastering XAML/.NET etc. has been just a waste. Who’s the daddy now?”. The cries got so loud recently that I find it difficult to sleep at night so let me take this opportunity and explain in plain English why Microsoft is doing what it’s doing with Windows 8.

There is nothing wrong with Windows…

..and this exactly is the fundamental problem. Microsoft finds it more and more difficult to persuade existing customers to upgrade to the latest and greatest version of the operating system. If you happen to live in the UK you must have seen the latest “I’m a PC” adverts where someone’s home is being converted into a computer shop and they leave it with their own chosen laptop/desktop once they’ve realised how much better modern computers are than their old, “good enough” PC. Why is Microsoft paying for those adverts? The only way to sell the new operating system is to sell it preinstalled on a new device. If you consider what home computers are used for (mainly browsing the net), there is simply no need to buy a new one unless the old one is dead. And would anyone you know outside of IT ever upgrade their OS? What for? And this is exactly Microsoft’s problem.

Come forth the consumer device…

So the PC is bought and stays at your average home forever (until it dies basically) whereas it’s remote cousin mobile phone is being upgraded every 12-24 months. And every one of those phones needs and OS license. Hmmm, now here’s an idea. How about the tablet fellow? What is his lifespan? As a (let’s face it) fashion accessory it is bound to have a similar “time to live” which means another OS license every 2-4 yrs. And this exactly is the ball Microsoft wants to play and I do not blame them for it.

September 18 2011
Newer Posts Older Posts