Thursday, October 1, 2009

SubSonic 3 with MVC and jQuery - Example (Part 1)

SubSonic 3, MVC and jQuery, like it was planned. Well, for me at least, it is a beautiful thing. I have been a big follower of SubSonic for many years now, most notably the 2.xx releases. SubSonic 3 has been out for a bit this year, and I thought that I would take a look. Turns out, it's a total rewrite (which is good in this case) that allows it to be more powerful. No more writing batch files to get your DAL files. I'd also like to give a big thanks to Rob Conery for SubSonic. Also, the guys (including Rob) at Microsoft that created "Nerd Dinner" and wrote a nice walkthrough realy helped get started.

If you want to skip to Part 2, you are more than welcome. :)

If you would like to download my example project, click here (look in the lower right corner of the page for the download link). This includes the good old Northwind database running locally in SQL Express. I also have included some files in the project that are "turned off" that match some of the Nerd Dinner files if you are looking to expand this example for yourself. :)

Things you will need for this setup:



So, to get SubSonic setup in your solution:
  • Download SubSonic 3
  • Extract the zip file and place the SubSonic folder on your local drive.
  • Create a class library project and add a reference to SubSonic.Core.dll
  • Simply drop the T4 (aka "tt") templates in your class library.
  • Add an app.config and a database connection string configure the ".ttinclude" file to point to your database and connection string.
  • After that, right-click on each of the "tt" files, and then click "Run Custom Tool" in Visual Studio. Very easy.
  • Compile the project and you're good to go.

Here is what the database connection part of the "Settings.ttinclude" looks like:
const string Namespace = "SubSonic.MVC.DataAccess";
const string ConnectionStringName = "NorthwindConnectionString";

//This is the name of your database and is used in naming
//the repository. By default we set it to the connection string name
const string DatabaseName = "Northwnd";

It's worth noting that the "SubSonic.MVC.DataAccess" Namespace can be anything that you want. So, if you want to call your Namespace "MonkeyCode.Bananas.DAL" you are more than welcome to do so.


The best advice I have for this is to loosely follow along in the "Nerd Dinner" pdf on building your ASP.NET MVC app. There is really no point for me to recreate the wheel that they have built. :) Download the PDF. What I will do is show examples of using SubSonic 3, MVC and jQuery to List, Detail, Insert, Update and Delete from the Products table in the NorthWind database.

Start Here (Setup):
  • After you have downloaded SubSonic 3, installed MVC 1.0 and .NET 3.5, and setup your data access class library with SubSonic 3 (from above):
    • Add a new project to the solution
    • Go to Visual C# > Web > ASP.NET MVC Web Application
    • For this example, name it WebApp and say OK
    • This will add and build your MVC Web App and create a Unit Test project for you


Modify the Master Page:
  • In the WebApp, go to Views > Shared > Site.Master and open it
  • Look for the menu links in the code and modify it like the example (below):
    <ul id="menu">              
    <li><%= Html.ActionLink("Home", "Index", "Home")%></li>
    <li><%= Html.ActionLink("About", "About", "Home")%></li>
    <li><%= Html.ActionLink("Products", "Index", "Products")%></li>
    </ul>


Add the Product Controller class:
  • Right-Click the Controllers folder > Add New Controller
  • Type in ProductsController for the name and check the checkbox for "Add action methods for Create, Update, and Details scenarios"

Setup Your Index View:
This is the heart of your Controller -- the Index. This is the default view that will show when someone goes to [yourdomain]/Products. First, what we'll do is query the Products table via SubSonic and then pass the list to the view. See the code below:
// DB Setup used for some actions
NorthwndDB db = new NorthwndDB();

// SubSonic query
SqlQuery sQuery = db
.Select
.From("Products");

var products = sQuery.ExecuteTypedList<Product>();

// Pass the list (aka Model) to the view
return View("Index", products);

Create the Index View:
Ok, this is really easy, just Right-Click on the Index() next to the ActionResult like in the image below.

Next, make sure the view name is "Index" and check "Create a strongly-typed view". Select your [SubSonic Namespace].Product data class from the list and finally choose "List" under View Content (see image below).


What happens is that Visual Studio will automatically create the folder "Products" under the "Views" folder and then create "Index.aspx" (i.e. /Views/Products/index.aspx) which is your Index view. Also, because you specified the data class and "list" type of view, it automatically created your HTML with all the fields from your data class.

Things to Note:
If you look at the top of the page in the code, it will look like this:
<%@ Page Title="" Language="C#" 
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<SubSonic.MVC.DataAccess.Product>>" %>

Notice that the "Inherits" property specifies the System.Web.Mvc.ViewPage Namespace and then breaks down further with IEnumerable and the actual data class from there.

Other things to note are:
  • The Model is inherited from the "product" class passed from the ProductsController. So, basically it's the same as saying "foreach (var product in products)."
    <% foreach (var item in Model) { %>

  • Links to other Views while passing the id of the current record are done like so:
    <a href="<%=Url.Action("Details", new { id = item.ProductID })%>">View Details</a>

  • Entity fields are displayed like this (reminds me of Classic ASP):
    <%= Html.Encode(item.ProductID) %>

  • Stand-alone, all inclusive links can be done like this:
    <%= Html.ActionLink("Create New", "Create") %>


At this point, you should be able to run your MVC web site and view the Products list (aka "Index") page.

View the Part 2 of the Series.