Developing a Web Application with TDD and ASP.NET MVC, Part 3: The MVC Structure

by Sekhat 21. December 2009 12:46

In my previous post we setup our solution. We got the main ASP.NET MVC project created as well as our testing project and we left it in a state to begin coding.

 

In this post however, I’m going to go over what MVC is and the directory structure of the MVC web project.

 

So what is MVC?

MVC is simply a design pattern, the three letters stands for Model View Controller. The MVC pattern tries to address the need to keep concerns separated, as the name suggests, into three pieces, the Model, the View and the Controllers.

 

The Model

The Model is simply your Domain, Business objects, Application Services (the classes that do stuff to your domain, but doesn’t have a place in a single domain object) and it also encompasses your Data Access Layer.

 

The Controllers

The Controllers are classes that contain actions, these actions are synonymous with actions of your website, for example, Your Account controller might have a login action that takes a username and password which would then log someone into the website. The Controllers sit between the view and model, asking questions and issuing orders to the model, and converting information from the model into information that view can use.

 

The Views

The Views are the code and HTML to turn the data passed from the controller into the HTML the browser gets, these are generally dumb and should contain no business logic within them.

 

The ASP.NET MVC Project Structure

imageAs you can see, the ASP.NET MVC project structure contains some similarities with standard ASP.NET Web Application structure. We have the Properties section, which holds the typical AssemblyInfo.cs. We have the App_Data folder which would hold your SQL Express data files. We also have a few others.

 

Content

This folder should hold the pure content parts of your site, in typical usage this would your style sheets and images.

 

Controllers

This folder should hold all your controllers.

 

Models

This folder holds the classes that make up your model. However this only really works if your model is small, most people will separate the model into it’s own assembly, as I will once I begin work on it.

 

Scripts

This folder should hold your client side scripts, such as Javascript scripts and libraries. You’ll find it comes pre-populated with Microsoft Ajax and JQuery.

 

Views

This folder will hold your views, normally sub-foldered into folders with the name of the controller that the views apply to. There is also often a Shared folder that would contain View specific items that are shared between everything, for example, controls and master pages.

 

The views folder also has it’s own Web.config, this is supposed to be there, as it configures some things (mainly validation related things) that should only be applied to your Views.

 

Files in Root

You’ll also notice we have a Default.aspx file in our root structure. This palms off any requests that make it to this page to the MVC handler, this shouldn’t need to be changed.

 

Global.asax contains (by default) the code to register the routes in our application. (More on routes in a later post)

 

And there is also a Web.config which is the main configuration file for the application and would be where you place any application configuration into.

 

Short and sweet, the end to another article

So there you have it, an explanation on MVC and the ASP.NET MVC structure. In the next article, we will get to write our first line of code. I promise.

Developing a Web Application with TDD and ASP.NET MVC, Part 2: Getting Started

by Sekhat 18. December 2009 13:00

In part 1 I laid out the requirements of the application and went over a simple design for the basics of the application.

In this part I’m going to go over setting up the project ready to begin coding.

Installing ASP.NET MVC

If you haven’t done so all ready, you will need to install ASP.NET MVC, which the installer can be found here.

As you can tell, I’m using version 1.0 as 2.0 is still in pre-RTM state. Installing ASP.NET MVC is simple and follows your standard, next, next, next, finish setup wizard.

And as an added bonus, MVC also works with Visual Web Developer 2008 Express, which is the free edition of Visual Studio for ASP.NET web development, which can be found here.

Choosing a Unit Testing Framework

Choosing a unit testing framework is simply a personal choice. Microsoft have included their own with Visual Studio 2008 (not express editions unfortunately), called MSTest. However my personal favourite at the moment is MBUnit/Gallio which can be found here. Most testing framework are fairly similar so if you are using a different one you should easily be able to translate my tests to your framework of choice.

Creating the MVC Project

If you start a new project in Visual Studio 2008 (or Visual Web Developer 2008) and select the project type “Web” under either Visual C# or Visual Basic (I’ve gone for C# as it’s my language of choice) you should see a template called “ASP.NET MVC Web Application”. Select the template and enter a Name for your project.

 

image

As you can see, I’ve given my solution the name of the software, and my project name is my solution name with .Web appended, this is my naming convention. This also makes sure that the default namespace for anything in my Web project is ArtistShowcase.Web .

Clicking OK will bring us on to the next part of the Project setup wizard.

image

As you can see, it’s asking me if I want to create a new Unit Test project for my MVC web project. As I’m going to be writing unit tests, I’m going to select yes. You’ll also notice that MBUnit shows up in here. This is small bonus for using MBUnit. MSTest also shows up in the drop down box, as you would expect, since it is Microsoft’s testing framework.

One thing to be aware of, is that you may never see this dialog if your using Visual Web Developer 2008 Express, as it' doesn’t support Unit Testing. So if you are using the Express edition, you’ll have to create your own class library that references your testing framework and your web project inside your solution.

After clicking OK will be present with our new solution, complete with Web Project and Testing Project.

 

image

This is a default project, that actually already contains some stuff, so there are a handful of unit tests that you can run, you can even run the project and get greeted with the basic MVC website.

image

However, I don’t want the default, and as much as starting off from this point can speed our development up, I want to start from scratch and go through all the headaches :)

So I’ve emptied the Content, Controllers and Models folder. I’ve deleted everything the views folder except the Web.config and I’ve also deleted the controllers folder from my test dll.

My Solution Explorer now looks like this:

image

Wrapping up

Okay that’s it for setting up the project and we should be okay to start coding and that’s all for this post.In the next post I’m going to go over the MVC directory structure and basic fundamentals of MVC and hopefully we’ll get to write our first line of code.

Developing a Web Application with TDD and ASP.NET MVC, Part 1: Application Design

by Sekhat 17. December 2009 12:59

Introduction

I’m going to start a series about writing a web application using Test Driven Development and ASP.NET MVC. I’ll be learning as I go and this will basically be documenting what I learn as I learn it and hopefully in the end it will also be of some help to other people.

Defining the Application

Okay, so the application we’re writing here is a web app that allows Artists to showcase their work. It’s a simple application in concept, so lets define some basic functionality that is required, this functionality is simply the first bit of functionality we’ll implement to consider it our first release.

So basic functionality:

  • Artist can upload images to a gallery
  • Artists can create new galleries giving each a title and description
  • Artist can give titles to images
  • Artists can give descriptions to images
  • Visitors can view images that have been organized in to galleries.
  • Visitors can download images that have been marked as downloadable.
  • There is an about page that the Artist can use to describe themselves.

Some functionality that isn’t so basic, but is wanted for the initial release

  • Images viewed from website should have a watermark applied.
  • Downloaded images do not have watermarks applied.

Some implied functionality

  • Login system, so that visitors can be prevented from uploading images and administrating galleries.

And then some non functionality stuff that should be true

  • Simple and well structured HTML that allows easy customization of website via CSS.

Initial Design

So first we need to translate these requirements into some basic design. But we’re doing TDD, I hear you cry, that should do the designing for us. Well the answer is no, we need to a basic design first to at least get an idea where to start. Our design needs to be basic so that it can be flexible because TDD may cause our design to emerge differently, via throwing up problems or issues or code smells that we haven’t thought of at this stage.

So lets take a look.

Users of the site

We have an Artist and a Visitor in terms of users of the site, only an Artist will be logging in, in order to administrate the site. This means that the defining difference between a Artist and a Visitor, is that an Artist is logged in and a Visitor isn’t.

So in our code, we’ll call an Artist a RegisteredUser and a visitor is called a GuestUser. Doesn’t match our stories, but it makes more sense in terms of web applications and are terms everyone is familiar with.

Our Domain

While I don’t plan on learning Domain Driven Design here, as I believe this site is too simple for such an approach since DDD is a way to manage complexity and complexity isn’t something we really have, we do have a domain. This is the domain of Artwork.

From our functionality list we can see that we have a Gallery and an Image

A Gallery has a title and a description and contains many images.

An image has a title and a description and will need some reference to the image data.

We also need someway to store information about the artist. We’ll call this the artist’s Profile

Data Storage

Our information needs to be stored somewhere, so looking at what we have and with a small amount of thinking, we have two places where we’ll need to store our data.

The Database and the File System.

The database will store details about our Users (or user in this case), galleries, images and the artists profile.

The file system will store the actual images in the format of the files uploaded.

Recap

Where’s the code and tests? Well we haven’t done any yet but we’ve outlined some basic things that allow us to see the basic direction of the application and should help us in figuring out where to get started. This initial design stage is important, and we’ll be doing design stages again in the future when we come to sit down and start writing units of functionality. In my head our order of work should be: Decide on piece of functionality to write, Basic design of functionality, Write tests and code in a test first manner allowing them to cause our final overall design to emerge and repeat.

See you next time.

An Email To Microsoft On the Microsoft Courier

by Sekhat 23. September 2009 16:28

This is an email that I wanted to send to microsoft, unfortunately I couldn't find an address to send it to, so I've posted it here in case anyone at microsoft finds it by accident.


Hello guys at Microsoft,

I have no idea if this email will hit anyone, it will mostly be bounced back I bet, but here I go anyway.

This is the first time I've been compelled to write an email to you guys, but what I've seen today has me nearly wetting myself with glee that I thought I should tell you.

Whoever brain child the Microsoft Courier was needs a raise and a standing ovation.

I've just watched the concept video, and if you guys make it work as the concept video shows (and I'm sure you'll take the time to make sure the experience is at least as good as the concept video) then I will be forever in your debt as it looks like a tool, a device, that I've been wishing for for quite some time now. It would solve a huge problem for me, that I didn't think would get solved.

I'm a developer, and I'm a developer with lots of ideas, ideas popping up left right and center for little projects that I would love to do (unfortunately they aren't the money making type of projects). When these ideas do pop up, I need to get the idea down. Currently I'm faced with three options.

1. Carry a paper notebook and a pen round with me, and write in that at any given moment, This gives me the best way to express my ideas, but the information is static, stuck the page and becomes hard to work with
2. Type it into my phone. This takes a long time, even with my on-screen keyboard, I also lose the expression given to me by paper
3. Put it into my computer. I can express the idea how I like here and it's not static, but that takes even longer and takes using multiple tools by which point the best parts of my thoughts have already scattered to the winds.

The Courier seems to solve all these problems for me. The lack of overhead and freedom to express my ideas like pen and paper and the ability to work with than information in a none static way is all win.

So, please, I emplore the courier team to get it working like the concept, and get it working like a dream, launch the product (in the UK!) and I'll be spamming the refresh key on the UK microsoft store on the launch date until I can press buy!

PS. Would be nice if the courier team got to see this email, I know it's always good to know that what your working on will truely help someone.

Databinding to ListControls, and fixing the peril of string assigned property names.

by Sekhat 11. September 2009 15:14

I came up with a solution today to a small little problem. The problem is when I'm data binding from a collection of objects to a list control.

myListControl.DataSource = myCollectionOfObjects;
myListControl.DataTextField = "Name";
myListControl.DataValueField = "ID";
myListControl.DataBind();

As you may (or may not know) what this will do is take myCollectionOfObjects, populates myListControl using the objects in that collection by making the ListItems value property equal to Name property on the object in the collection and the Text value property equal to the ID of the object.

Assuming my object is defined as so:

public class MyObject
{
    public int ID { get; set; }
    public string Name { get; set; }
}

and assuming the objects in myCollectionOfObjects have the following data:

IDName
1My Object 1
2My Object 2
3My Object 3
4My Object 4

I'd end up with this:

Which is all well and good. But the problem is back up with the C# code, I tell it which properties of my class I'm using for data binding via strings. This means there is no compile-time checking against those names and if those names change I won't know until runtime, when my lovely web-app crashes and burns spectacularly with a cryptic error message.

So I set about to resolve this, and I did, thanks to the wonders of extension methods, lamdas and expression trees.

I wrote the following extension class for ListControls:

public static class ListControlExtensions
    {
        public static void SetDataBindForList(
            this ListControl control, IEnumerable dataSource, Expression> textField, Expression> valueField)
        {
            control.DataSource = dataSource;

            SetDataTextField(control, textField);

            SetDataValueField(control, valueField);
        }

        public static void SetDataTextField(this ListControl control, Expression> textField)
        {
            var memberExpression = textField.Body as MemberExpression;

            if (IsProperty(memberExpression))
            {
                control.DataTextField = memberExpression.Member.Name;
            }
            else
                throw new ArgumentException("textField is not a property", "textField");
        }

        public static void SetDataValueField(this ListControl control, Expression> valueField)
        {
            var memberExpression = valueField.Body as MemberExpression;

            if (IsProperty(memberExpression))
            {
                control.DataValueField = memberExpression.Member.Name;
            }
            else
                throw new ArgumentException("valueField is not a property", "valueField");
        }

        private static bool IsProperty(MemberExpression memberExpression)
        {
            if (memberExpression == null ||
                memberExpression.Member.MemberType != System.Reflection.MemberTypes.Property)
                return false;
            
            return true;
        }
    }

Here I have three extension methods (and one private helper method) where the first method, SetDataBindForList, is used to setup the data binding and calls the other two to set the DataTextField and DataValueField respectively.

SetDataTextField is used to set the DataTextField if you want to do it by itself and likewise with SetDataValueField except it's for DataValueField.

The new code I write when I want to databind to a ListControl now is this:

myListControl.SetDataBindForList(
    myCollectionOfObjects,
    o => o.Name,
    o => o.ID);

Thanks to the type inference of the compiler this becomes one very simple call and it's checked at compile time for correctness on my field names. Pretty neat huh?

-- Edit: It appears my code plugin for blogengine.net is a bit silly with the whole formatting thing. I'll sort it out this evening. -- Edit 2: Tidy complete :)

Type Safe ViewState Retrieval

by Sekhat 30. August 2009 14:20

Often when I'm using the view state I'll have to code nice getters in my control or page to get me a value from the view state as the type I stored it in, for example:

public int PageCount
{
    get
    {
        object viewStateObject = ViewState["PageCount"];

        if (viewStateObject != null && viewStateObject is int)
        {
            return (int)viewStateObject;
        }
    
        return 0;
    }

    set
    {
        ViewState["PageCount"] = value;
    }
}

As you can probably guess this gets pretty damn repetitive once you have more than one item to retrieve from view state.

So I decided to create a couple of nice extension methods to help with this, here's the code:

    public static class StateBagExtensions
    {
        ///
        /// Gets an item from a state bag
        ///
        /// The type of item to retrieve
        ///
"stateBag" />The state bag to retrieve the item from
        /// "key" />The key of the item to retrive from the state bag
        /// The item retrieved from the state bag or the default value
        ///
        ///
        /// The default value is retrived using the default(T) call.
        ///
        ///
        /// The default value is only returned if one of the following conditions is met:
        ///
        /// The object for the given key does not exist in the state bag
        /// The object for the given key retrieves a null value from the state bag
        /// The object for the given key is not of the requested type
        ///
        ///
        public static T GetOrDefault(this StateBag stateBag, string key)
        {
            return GetOrDefault(stateBag, key, default(T));
        }

        ///
        /// Gets an item from a state bag
        ///
        /// The type of item to retrieve
        ///
"stateBag" />The state bag to retrieve the item from
        /// "key" />The key of the item to retrive from the state bag
        /// "defaultValue" />The value to use as the default value
        /// The item retrieved from the state bag or the default value
        ///
        ///
        /// The default value is only returned if one of the following conditions is met:
        ///
        /// The object for the given key does not exist in the state bag
        /// The object for the given key retrieves a null value from the state bag
        /// The object for the given key is not of the requested type
        ///
        ///
        public static T GetOrDefault(this StateBag stateBag, string key, T defaultValue)
        {
            object viewStateObject = stateBag[key];

            if (viewStateObject != null && viewStateObject is T)
            {
                return (T)viewStateObject;
            }

            return defaultValue;
        }
    }

Which means now my repetitive view state accessing properties now become:

public int PageCount
{
    get
    {
        return ViewState.GetOrDefault("PageCount", 0);
    }

    set
    {
        ViewState["PageCount"] = value;
    }
}

Which means accessing my viewstate is much simpler and also a hell of a lot DRYer.

Till next time :)

Trying out BlogEngine.net

by Sekhat 10. July 2009 12:35

And heres my first post with BlogEngine.net.

So far very impressed with the polish of this blog enigne. But "so far" is currently about 3 minutes after setting it up.

That be all for now :)