WebMatrix - A First Application

This article will take a first look at WebMatrix - Microsoft's new IDE for developing Web Pages applications. In it, I will cover a number of the core features that will make Web Matrix the ideal starter's web development framework as I create a very simple application.

NOTE

This article is based on WebMatrix Beta 1. Some items have changed in Beta 2, so the code may not run as-is. To check what has changed, please refer to this article: WebMatrix Beta 2 Changes

 

The web site I'm going to build will not do very much - it will simply display some books from a database. However, I will take a look at working with Sql Server Compact Edition within the WebMatrix IDE, the new Razor syntax, the new cshtml file type and some of the inbuilt helpers. I plan to look at more Web Pages features as I build on the functionality of the application over the course of additional articles. All of the code for this article is available as a download (link at bottom).

To start with, I need to create a site, so I start up WebMatrix, and choose Site From Template, then I select the Empty Site option. I save this as BookSite.

From this opening screen, we can manage files within the application, databases and SEO analysis of the site. For this example, I shall only be using the first two options. First, a database driven site needs a database, so clicking the Manage Databases link in the middle of the wscreen, or the Databases link in the left pane will get me to where I need to be. The next screen includes an invitation to add a new database:

By default, an App_Data folder is created, and within that, a database with the same name as the site. In this case, BookSite.sdf. I don't like that, so I would like to right click on the database and choose to rename it to Books. However, that is not an option in the Beta, so I have to choose Files in the left panel, and rename it from there once I have opened the App_Data folder. While I am in the Files View, I also delete the default index.html file, and add a new file called Default.cshtml, by either right clicking on BookSite and choosing New File, or by clicking the New option in the Files menu at the top of the workspace.

Going back the the Database view, I click the New Table button on the menu, and begin to add a table:

When finished, it has four fields and is saved as Authors:

I then add two more tables: Categories, and Books with the following definitions:

If I click the Data button on the main menu, I can start adding data directly to the tables:

OK. Now switching back to the File view, I open Default.cshtml, and at the top of the file, open a new code block with @{ }:

This is the new Razor syntax. The @ sign followed by a pair of braces denotes a multi-line code block, and could be thought of as equivalent to a non-code behind script runat="server" block. I'm going to test reading from the database, so I shall add some code to do that:

Database is a new class which provides an easy set of methods for working with databases. One of the methods - OpenFile() sets up a connection and opens the database whose file name is passed in to the method. The next line of code is a simple SQL query.

I add some more code to the body element of the page:

More Razor syntax: Database.Query() is a method that returns an IEnumerable<object>. The SQL is executed against the database, and the rows of data returned are converted into a collection of objects, with the database field names exposed as properties of those objects. foreach is preceded with an @ sign, but no braces. This is because there is only a single line of code. The literal text and html markup in the second line is not considered part of the code block, but it is recognised by the Razor parser as belonging to the each iteration of the loop, and the closing brace confirms that. Inline expressions or variables are also preceded by the @ sign, as in @row.Title. The Razor parser will recognise these and replace them appropriately. You can see from the shading in the image that the IDE recognises what is code and what is static html. We can see the result of this operation by clicking Launch in the menu, or simply hitting F12:

Looks fairly dull, so let's add some css to the site. Going back to the Files menu, if not already in it, I create a new folder called Styles by right-clicking on the site and choosing New Folder, and in that, I add a new file of type CSS. I leave that named as StyleSheet.css. In that, I add the following simple css rules:

This needs to be associated with the page, so I use one of the new helpers: Href(path), which creates a browser compatible URL from the local file name:

Notice again how the helper acquires a shaded background in the IDE. I amend Default.aspx to show more data:

Running this in the browser results in the desired effect...

...but also shows that some of the descriptions have typos in them. Entering data directly into a database is a pain, but I shall look at providing some editing functionality in a forthcoming article. In the meantime, some users of this application might not be interested in seeing such a wide ranging list of books. They may only be interested in seeing one category of books, so that's what I shall work on next.

The plan is to offer the user a category selection option prior to displaying books. They can either choose a category, or choose to see all books. As well as the title, author, ISBN and the description provided for each book, the category which the book belongs to will also be displayed. The first thing to do is to amend the existing SQL to bring in the additional data, and then to add some more to get the categories:

I need something to consume and display the categories so that the user can select one of them. An html select element fits this bill, and this goes at the top of the body area within the page:

At the moment, there are no helpers for the dropdown list, or select list. It is possible to template a helper to manage this kind of thing, but reusable code including helpers is something for a future article. The code is pretty simple to understand - a form tag is added, and within that, a select list with a default value hard-coded. From there, the result of the categories query is iterated to populate the option values and the display values for the select. Finally, a submit button is provided to post the form back, and the form itself is closed off.

There are some additional changes required. When the page first loads, I only want to display the select list and button. I will only show books when the user has made a selection and posted the form/page back. there are two options here - the user may choose the default one which will show all books, or they may decide to choose a particular category. If the default option is selected, the value passed to the server for CategoryID (the name of the select list) will be an empty string. If not, it will be a number. A helper function assists in identifying which it is - a number or not. The helper is IsInt(). You can see this being applied to Request["CategoryID"] in the code below, which only runs if the form has been posted - IsPost() is the property that helps determine that. The code that runs if the value is a number adds a bit to the SQL to be executed, including a parameter value for the CategoryId field in the database:

Parameter place holders need to be named in a certain way, starting with @0, then @1, then @2 and so on. Internally, the Database.Query() method will run through the collection of parameter values passed in and attempt to match them to a parameter placeholder based on their index within the collection. The index starts at 0, so names of placeholders is important, as is the order in which the parameter values are passed in. And finally, the code that runs to display the books is also wrapped in the IsPost() condition further down the page:

Here, the Database.Query() method is shown including a parameter value for the CategoryId value. If the SQL does not include the extra WHERE part because the user chose the default option, the Request["CategoryID"] value passed in is effectively ignored. There's no parameter placeholder to match it up with.

Finally, the last two images show the page as it first loads, and the result of selecting the Javascript category:

And that's it for now. While it's certainly no rival to Amazon, some of the new WebMatrix, Razor and Sql Server CE features have been covered. There are a lot of other features that haven't even been touched on, and I intend to experiment more with this new set of toys and publish the results as articles. The next article will examine how to provide a consistent look and feel for the site. In the meantime, the site files for this article, together with the database etc are available in the download. If you want to run it, get hold of WebMatrix and use the Site From Folder option once you have unzipped the download.

Date Posted: Tuesday, July 6, 2010 9:35 PM
Last Updated: Tuesday, November 11, 2014 8:12 AM
Posted by: Mikesdotnetting
Total Views to date: 43151

14 Comments

Tuesday, July 6, 2010 10:13 PM - Thomas Jespersen

I can't belive we have come this long since classic ASP. SQL embedded directly in a HTML file... You gotta be kidding me.

I belive I saw this exact demo in 1997 in Visual InterDev.

Love the Razor syntax though.

Tuesday, July 6, 2010 10:23 PM - Mike

@Thomas

There's no reason why you can't use LINQ to SQL, or EF etc with Web Pages, but I think you need to understand the audience that this platform is aimed at.

Wednesday, July 7, 2010 1:35 AM - Dan Martin

Yeah I think Scott Hanselman summed it up nicely in his post about WebMatrix:

"If you're reading this blog, and you're not my Wife, this tool probably isn't for you. (Hi, wife.) However, the pieces that make up WebMatrix probably are. "

It's a nice introduction to IIS Express and Razor.

Wednesday, July 7, 2010 6:23 PM - Artem Gassan

This make me sick every time I see stuff like this. I truly don't understand why people trying to change ASP.NET into procedural language. Main reason we use C# code behind to avoid spaghetti code like this. If people want to learn ASP.NET learn it right way and not this way. This is full degradation. I feel someone want to put in his resume that he knows ASP.NET and C# when he does even understand methodology behind it.

Wednesday, July 7, 2010 6:49 PM - Mike

@Artem

I have interviewed plenty of "experienced" ASP.NET devs who don't even understand the HTML that their drag and drop controls render. I mean, seriously - how much does Web Forms encourage the abuse of the span tag? These people would find WebMatrix too difficult to use because they don't know enough of the basics. They will stick with Web Forms because they just "don't get MVC".

It's not the tools that make a good developer - it's having a passion and desire to learn their craft. If tools like WebMatrix make it easier for people to get started on that journey, where is the problem in that?

Thursday, July 8, 2010 7:32 AM - aks

How does the engine figure out Request.CategoryID is to be passed in @0?

if(Request["CategoryID"].IsInt()){
sql += " WHERE Books.CategoryId = @0";

Thursday, July 8, 2010 8:30 AM - Mike

@aks

The Database.Query() method accepts two arguments - a string representing the SQL, and a variable number of values which become an array. These represent the parameter values. Internally, the method loops through that array, and creates parameters. The name of the parameter is the index of the array.ToString(), and the value for the parameter is the array element value at that index.

If you were able to attach a profiling tool to SQL Server CE (I don't know whether there is such a thing), you will see the command being passed something like this:

'Select * From Table WHERE ID = @0', @0=4"

where 4 is the CategoryID value. The first bit is your SQL, and the second bit (after the comma) is the parameter and its value are passed for the engine to substitute into the SQL before executing it.

Wednesday, August 11, 2010 10:30 AM - dotnetcoder

Mike, It would be so awesome if you could do a series on how to build a blog or a simple cms or a simple e-commerce site. Than we could really learn something useful. Would you consider something like that? Thanks!

Wednesday, August 11, 2010 6:35 PM - Mike

@dotnetcoder

I'll certainly consider something like that. One of the difficulties I have is on knowing at which point to start. Since WebMatrix is primarily targeted at people who have very little or no experience in web development, I'm not sure whether to spend much time explaining HTML, CSS, database design etc as part of that type of article series. But let me think about it :o)

Sunday, September 26, 2010 6:17 AM - ante marcus

i've been doin some Razor for 4 days , and the fact i dont have to worry about code behind or MVC is nice.
Cool tool for little apps or micro sites , . teenagers can easily build professional like projects with it , nothing wrong with that;

Saturday, February 26, 2011 4:36 AM - Hamid


Dear Mike

Please write a article that how we use Microsoft entity framework and sql stored procedures in web matrix application?

Monday, March 7, 2011 12:56 PM - AlexPetrescu

Hi,

I see in all the WebMatrix tutorials on the web that Database.Open is always used but never Database.Close. How is this being handled, is the connection closed behind the scenes?

Thank you!

Monday, March 7, 2011 7:03 PM - Mike

@AlexPetrescu

Most of the samples you see make use of Sql CE 4.0, which runs within the application's process memory space. Therefore there is no inter-process communication. The database actually fires up when the application starts, and closes when the application stops.

With other databases, such as SQL Server, when you open a connection, you are making an out-of-process call, and .NET has no mechanism for keeping handles on these, which is why you should explicitly close connections. That way, they are marked as finished with, and can be returned to the connection pool for reuse.

The WebMatrix.Data.Database class implements IDisposable so if your database is NOT Sql CE, you should employ using statements:

using(var db = Database.Open(...)){
....
}
            

Wednesday, January 30, 2013 7:40 PM - William Ogura

How do you persist dropdownlist selection after hitting submit
Add your comment

If you have any comments to make about this article, please use this form to do so. Make sure that your comment relates specifically to the article above. More general comments can be posted through the form on the Contact page.

Please note, all comments are moderated, and some may not be published. The kind of things that will ensure your comment is deleted without ever seeing the light of day are as follows:

  • Not relevant to the article
  • Gratuitous links to your own site or product
  • Anything abusive or libellous
  • Spam
  • Anything in a language I don't understand including gibberish.

I do not pass email addresses on to spammers, so a valid one will assist me in responding to you personally if required.

Recent Comments

Allen Michaels 12/17/2014 4:37 PM
In response to Cascading DropDownLists with jQuery and ASP.NET
Fantastic thank you so much!...

Emily 12/17/2014 12:36 PM
In response to Parameterized IN clauses with ADO.NET and LINQ
Thanks, very helpful!!!! Can i use this for multiple in's ????? IN (.....) and IN(...) and IN...

sss 12/16/2014 3:06 PM
In response to Solving the Operation Must Use An Updateable Query error
good...

Gjuro 12/15/2014 10:30 PM
In response to Examining the Edit Methods and Edit View
You have one fromr (and it should be from, I suppose). :-)...

Gjuro 12/15/2014 10:27 PM
In response to Adding Search
Hi, thnx for all this C#->VB translations. Yet, the following code block is (slightly) in error it a...

Scot 12/14/2014 1:39 PM
In response to Entity Framework 6 Recipe - Alphabetical Paging In ASP.NET MVC
Thanks,Mike I found solution....

Gjuro 12/13/2014 10:52 PM
In response to Accessing Your Model's Data from a Controller
The article mentions "Creating an Entity Framework Data Model for an ASP.NET MVC Application" (at is...

Samuel 12/13/2014 8:40 AM
In response to Displaying The First n Characters Of Text
I have failed to use the extension because it throws an error that it doesn't recognise the chop be...

Ignas 12/12/2014 5:11 PM
In response to Cleaner Conditional HTML Attributes In Razor Web Pages
Any suggestions for Html Helper elements with HtmlAttributes, when you need to conditionally set it...

Gautam 12/11/2014 8:50 PM
In response to Validation In Razor Web Pages 2
Hi Mike Is this required for V3, non html helper input...