February 2011 - Posts - Jon Galloway

February 2011 - Posts

Generating EF Code First model classes from an existing database

Entity Framework Code First is a lightweight way to "turn on" data access for a simple CLR class. As the name implies, the intended use is that you're writing the code first and thinking about the database later.

However, I really like the Entity Framework Code First works, and I want to use it in existing projects and projects with pre-existing databases. For example, MVC Music Store comes with a SQL Express database that's pre-loaded with a catalog of music (including genres, artists, and songs), and while it may eventually make sense to load that seed data from a different source, for the MVC 3 release we wanted to keep using the existing database. While I'm not getting the full benefit of Code First - writing code which drives the database schema - I can still benefit from the simplicity of the lightweight code approach.

Scott Guthrie blogged about how to use entity framework with an existing database, looking at how you can override the Entity Framework Code First conventions so that it can work with a database which was created following other conventions. That gives you the information you need to create the model classes manually. However, it turns out that with Entity Framework 4 CTP 5, there's a way to generate the model classes from the database schema. Once the grunt work is done, of course, you can go in and modify the model classes as you'd like, but you can save the time and frustration of figuring out things like mapping SQL database types to .NET types.

Note that this template requires Entity Framework 4 CTP 5 or later. You can install EF 4 CTP 5 here.

Step One: Generate an EF Model from your existing database

The code generation system in Entity Framework works from a model. You can add a model to your existing project and delete it when you're done, but I think it's simpler to just spin up a separate project to generate the model classes. When you're done, you can delete the project without affecting your application, or you may choose to keep it around in case you have other database schema updates which require model changes.

I chose to add the Model classes to the Models folder of a new MVC 3 application. Right-click the folder and select "Add / New Item..."

 

EF Code First Models from an existing database

Next, select ADO.NET Entity Data Model from the Data Templates list, and name it whatever you want (the name is unimportant).

EF Code First Models from an existing database

 

Next, select "Generate from database." This is important - it's what kicks off the next few steps, which read your database's schema.

EF Code First Models from an existing database

 

Now it's time to point the Entity Data Model Wizard at your existing database. I'll assume you know how to find your database - if not, I covered that a bit in the MVC Music Store tutorial section on Models and Data. Select your database, uncheck the "Save entity connection settings in Web.config" (since we won't be using them within the application), and click Next.

EF Code First Models from an existing database

 

Now you can select the database objects you'd like modeled. I just selected all tables and clicked Finish.

EF Code First Models from an existing database

 

And there's your model. If you want, you can make additional changes here before going on to generate the code.

EF Code First Models from an existing database

 

Step Two: Add the DbContext Generator

Like most code generation systems in Visual Studio lately, Entity Framework uses T4 templates which allow for some control over how the code is generated. K Scott Allen wrote a detailed article on T4 Templates and the Entity Framework on MSDN recently, if you'd like to know more. Fortunately for us, there's already a template that does just what we need without any customization.

Right-click a blank space in the Entity Framework model surface and select "Add Code Generation Item..."

EF Code First Models from an existing database

Select the Code groupt in the Installed Templates section and pick the ADO.NET DbContext Generator. If you don't see this listed, make sure you've got EF 4 CTP 5 installed and that you're looking at the Code templates group. Note that the DbContext Generator template is similar to the EF POCO template which came out last year, but with "fix up" code (unnecessary in EF Code First) removed.

EF Code First Models from an existing database

 

As soon as you do this, you'll two terrifying Security Warnings - unless you click the "Do not show this message again" checkbox the first time. It will also be displayed (twice) every time you rebuild the project, so I checked the box and no immediate harm befell my computer (fingers crossed!).

EF Code First Models from an existing database

 

Here's the payoff: two templates (filenames ending with .tt) have been added to the project, and they've generated the code I needed.

 EF Code First Models from an existing database

The "MusicStoreEntities.Context.tt" template built a DbContext class which holds the entity collections, and the "MusicStoreEntities.tt" template build a separate class for each table I selected earlier. We'll customize them in the next step.

I recommend copying all the generated .cs files into your application at this point, since accidentally rebuilding the generation project will overwrite your changes if you leave them there.

Step Three: Modify and use your POCO entity classes

Note: I made a bunch of tweaks to my POCO classes after they were generated. You don't have to do any of this, but I think it's important that you can - they're your classes, and EF Code First respects that. Modify them as you need for your application, or don't.

The Context class derives from DbContext, which is what turns on the EF Code First features. It holds a DbSet for each entity. Think of DbSet as a simple List, but with Entity Framework features turned on.

 

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace EF_CodeFirst_From_Existing_Database.Models
{
    using System;
    using System.Data.Entity;
    
    public partial class Entities : DbContext
    {
        public Entities()
            : base("name=Entities")
        {
        }
    
        public DbSet<Album> Albums { get; set; }
        public DbSet<Artist> Artists { get; set; }
        public DbSet<Cart> Carts { get; set; }
        public DbSet<Genre> Genres { get; set; }
        public DbSet<OrderDetail> OrderDetails { get; set; }
        public DbSet<Order> Orders { get; set; }
    }
}

It's a pretty lightweight class as generated, so I just took out the comments, set the namespace, removed the constructor, and formatted it a bit. Done.

If I wanted, though, I could have added or removed DbSets, overridden conventions, etc.

using System.Data.Entity;

namespace MvcMusicStore.Models
{
    public class MusicStoreEntities : DbContext
    {
        public DbSet     Albums  { get; set; }
        public DbSet     Genres  { get; set; }
        public DbSet    Artists { get; set; }
        public DbSet      Carts { get; set; }
        public DbSet     Orders { get; set; }
        public DbSet OrderDetails { get; set; }
    }
}

Next, it's time to look at the individual classes. Some of mine were pretty simple - for the Cart class, I just need to remove the header and clean up the namespace.

//------------------------------------------------------------------------------
// 
//     This code was generated from a template.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// 
//------------------------------------------------------------------------------

namespace EF_CodeFirst_From_Existing_Database.Models
{
    using System;
    using System.Collections.Generic;
    
    public partial class Cart
    {
        // Primitive properties
    
        public int RecordId { get; set; }
        public string CartId { get; set; }
        public int AlbumId { get; set; }
        public int Count { get; set; }
        public System.DateTime DateCreated { get; set; }
    
        // Navigation properties
    
        public virtual Album Album { get; set; }
    
    }
}

I did a bit more customization on the Album class. Here's what was generated:

//------------------------------------------------------------------------------
// 
//     This code was generated from a template.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// 
//------------------------------------------------------------------------------

namespace EF_CodeFirst_From_Existing_Database.Models
{
    using System;
    using System.Collections.Generic;
    
    public partial class Album
    {
        public Album()
        {
            this.Carts = new HashSet();
            this.OrderDetails = new HashSet();
        }
    
        // Primitive properties
    
        public int AlbumId { get; set; }
        public int GenreId { get; set; }
        public int ArtistId { get; set; }
        public string Title { get; set; }
        public decimal Price { get; set; }
        public string AlbumArtUrl { get; set; }
    
        // Navigation properties
    
        public virtual Artist Artist { get; set; }
        public virtual Genre Genre { get; set; }
        public virtual ICollection Carts { get; set; }
        public virtual ICollection OrderDetails { get; set; }
    
    }
}

I removed the header, changed the namespace, and removed some of the navigation properties. One nice thing about EF Code First is that you don't have to have a property for each database column or foreign key. In the Music Store sample, for instance, we build the app up using code first and start with just a few columns, adding in fields and navigation properties as the application needs them. EF Code First handles the columsn we've told it about and doesn't complain about the others. Here's the basic class:

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using System.Collections.Generic;
namespace MvcMusicStore.Models
{
    public class Album
    {
        public int      AlbumId    { get; set; }
        public int      GenreId    { get; set; }
        public int      ArtistId   { get; set; }
        public string   Title      { get; set; }
        public decimal Price       { get; set; }
        public string AlbumArtUrl  { get; set; }
        public virtual Genre  Genre                     { get; set; }
        public virtual Artist Artist                    { get; set; }
        public virtual List OrderDetails   { get; set; }
    }
}

It's my class, not Entity Framework's, so I'm free to do what I want with it. I added a bunch of MVC 3 annotations for scaffolding and validation support, as shown below:

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using System.Collections.Generic;

namespace MvcMusicStore.Models
{
    [Bind(Exclude = "AlbumId")]
    public class Album
    {
        [ScaffoldColumn(false)]
        public int      AlbumId    { get; set; }

        [DisplayName("Genre")]
        public int      GenreId    { get; set; }

        [DisplayName("Artist")]
        public int      ArtistId   { get; set; }

        [Required(ErrorMessage = "An Album Title is required")]
        [StringLength(160)]
        public string   Title      { get; set; }

        [Required(ErrorMessage = "Price is required")]
        [Range(0.01, 100.00,
            ErrorMessage = "Price must be between 0.01 and 100.00")]
        public decimal Price       { get; set; }

        [DisplayName("Album Art URL")]
        [StringLength(1024)]
        public string AlbumArtUrl { get; set; }

        public virtual Genre  Genre                     { get; set; }
        public virtual Artist Artist                    { get; set; }
        public virtual List<OrderDetail> OrderDetails   { get; set; }
    }
}

The end result was that I had working EF Code First model code for the finished application. You can follow along through the tutorial to see how I built up to the finished model classes, starting with simple 2-3 property classes and building up to the full working schema.

Thanks to Diego Vega (on the Entity Framework team) for pointing me to the DbContext template.

IE9 RC fixed the “Internet Explorer cannot display the webpage” error when running an ASP.NET application in Visual Studio

One of the obstacles ASP.NET developers faced in using the Internet Explorer 9 Beta was the dreaded “Internet Explorer cannot display the webpage” error when running an ASP.NET application in Visual Studio.

IE9 Beta - Cannot Display Page Error with ASP.NET Development Server

In the bug information on Connect (issue 601047), Eric Lawrence said that the problem was due to “caused by failure to failover from IPv6 to IPv4 when the connection is local.”

Robert MacLean gives some more information as what was going wrong:

“The problem is Windows, especially since it assumes IPv6 is better than IPv4. Note […] that when you ping localhost you get an IPv6 address. So what appears to be happening is when IE9 tries to go to localhost it uses IPv6, and the ASP.NET Development Server is IPv4 only and so nothing loads and we get the error.”

The Simple Fix - Install IE 9 RC

Internet Explorer 9 RC fixes this bug, so if you had tried IE 9 Beta and stopped using it due to problems with ASP.NET development, install the RC.

The Workaround in IE 9 Beta

If you're stuck on IE 9 Beta for some reason, you can follow Robert's workaround, which involves a one character edit to your hosts file. I've been using it for months, and it works great.

  1. Open notepad (running as administrator) and edit the hosts file (found in %systemroot%\system32\drivers\etc)
  2. Remove the # comment character before the line starting with 127.0.0.1
  3. Save the file - if you have problems saving, it's probably because you weren't running as administrator

When you're done, your hosts file will end with the following lines (assuming you were using a default hosts file setup beforehand):

# localhost name resolution is handled within DNS itself.
    127.0.0.1       localhost
#    ::1             localhost

Note: more information on editing your hosts file here.

This causes Windows to default to IPv4 when resolving localhost, which will point to 127.0.0.1, which is right where Cassini - I mean the ASP.NET Web Development Server - is waiting for it.

Download mvcConf session videos with a PowerShell script (should work with other Channel 9 feeds, too)

I tweaked my NuGet downloader PowerShell script to handle the Channel 9 media feeds, so you can grab a local copy of all session videos in the format of your choice:

  • WMV (high and low quality)
  • MV4 (high and low quality)
  • MP3
  • WMA

There are a few ultra-premium professional features in this script, like a download progress bar, logic to skip download if you’ve already grabbed some of the files, and pre-written filter strings to let you select the media type. Despite these advanced features, I pledge to think about keeping this script free for community use.

Just kidding, it’s Public Domain, like all the code on my blog.

Works with other Channel 9 feeds

The first setting is the feed url, which is different for each series or show. You can browse to a show / series, grab the RSS feed link, and update the script.

Why a script to download from an RSS feed?

This is a great question. The deal is that the Channel 9 RSS feed includes the low quality video file as the default enclosure. That makes sense in most cases, but not when you need to read code. I already had a script which did most of the work, so I just added some logic to grab the media URL based on some (admittedly a bit ugly) string matching.

I wouldn’t be surprised if there’s a smarter way, like adding a parameter to the RSS feed or something. Until I hear differently, I assert that this is a great script because it works on my machine.

Note: Now that I’ve got a local copy, I’ll be uploading a torrent via ClearBits, which is a bit more efficient than having everyone pull them from Channel 9.

How To Use

(same instructions as the NuGet downloader script – see that post for a little more detail and screenshots)

The easiest way to use the following script (included at the end of this post) is to open it in the PowerShell ISE (Integrated Scripting Environment). If you're running Windows 7 , just tap the Windows key and type "powershell" - you should see "Windows PowerShell ISE" show up in your Programs list. Paste in the code, save it if you'd like, and hit F5 to run it.

mvcConf Downloader

You can also paste the whole script into the NuGet Package Manager Console, but you lose the beautiful progress bar and maybe some other features.

There are a few settings you may want to tweak:

  • feedUrl indicates the feed you’re downloading. It’s already set for mvcConf, but you can change it to download other series.
  • overwrite indicates whether you want to force downloading even if you already have a file. It defaults to false, meaning that files you’ve already got will be skipped.
  • destinationDirectory defaults to a new folder called mvcConfVideo in your Documents folder. You can change that to any path you’d like.
  • downloadFilter determines which media type will be downloaded. Default is HD WMV. To change the media type, just copy the download filter string from the list shown below.

The Script

# --- settings ---
$feedUrl = "http://channel9.msdn.com/Series/mvcConf/RSS"
$overwrite = $false
$destinationDirectory = join-path ([Environment]::GetFolderPath("MyDocuments")) "mvcConfVideo"

# Download filter options
# "_high_ch9\.mp4"               - High quality mp4
# "_low_ch9\.mp4"                - Low quality mp4
# "_2MB_ch9\.wmv"                - High quality wmv (default)
# "^((?>(?!_2MB).)*)_ch9\.wmv"   - Low quality wmv (excluding high quality wmv)
# "_ch9\.wma"                    - WMA (audio)
# "_ch9\.mp3"                    - MP3
$downloadFilter = "_2MB_ch9\.wmv"

# --- locals ---
$webClient = New-Object System.Net.WebClient

# --- functions ---
function DownloadEntries {
 param ([string]$feedUrl) 
 $feed = [xml]$webClient.DownloadString($feedUrl)
 $progress = 0
 $entries = $feed.rss.channel.item.Length
 $feed.rss.channel.item | foreach {
    $url = New-Object System.Uri(($_.group.content | where {$_.url -match $downloadFilter}).url)
    $fileName = $url.Segments[-1]
    $saveFileName = join-path $destinationDirectory $fileName
    $pagepercent = [Math]::floor((++$progress)/$entries*100)
    if ((-not $overwrite) -and (Test-Path -path $saveFileName)) 
    {
        write-progress -activity "$fileName already downloaded" -status "$pagepercent% of current page complete" -percentcomplete $pagepercent
    }
    else 
    {
        write-progress -activity "Downloading $fileName" -status "$pagepercent% of current page complete" -percentcomplete $pagepercent
        $webClient.DownloadFile($url, $saveFileName)
    }
  }
}  

# --- do the actual work ---

# if dest dir doesn't exist, create it
if (!(Test-Path -path $destinationDirectory)) { New-Item $destinationDirectory -type directory }

DownloadEntries $feedUrl
Posted by Jon Galloway | 3 comment(s)
Filed under: ,

mvcConf 2 - All session videos are up, time for a recap

Dear MVC community: You are awesome

Thanks for making mvcConf 2 a much bigger success than we'd ever anticipated! mvcConf grew out of the C4MVC meetings, with the first mvcConf event in July 2010. Following that event, we talked about what went well and what we'd like to do for the next event, and we all agreed that we wanted to go for it and see how big we could expand. Here's how the progression went:

Event Live Attendance Overall Feel
C4MVC meetings 30-50 User group
mvcConf 1 500 Code Camp
mvcConf 2 10,000 Conference

Stats

Here's a look at the participation during the event:

  • 4900 unique live viewers of the live video stream throughout the day
  • 2450 peak video viewership (for Scott Guthrie and Phil Haack sessions), over 1000 viewers at all times throughout the day
  • 4 concurrent Live Meeting tracks, in addition to the live video stream
  • 1100 peak attendance for Live Meeting sessions (concurrent with and in addition to the live video stream)
  • 5900 hours of attendance by Live Meeting participants
  • Top on-demand video (of those available thus far) – Scott Guthrie KeynoteOver 29,000 views in the week since the event
  • Top Live Meeting session – BDD in ASP.NET MVC using SpecFlow, WatiN and WatiN Test Helpers by Brandon Satrom – 424 attendees
  • Over 1500 tweets, overwhelmingly positive
  • Top rated session – MVC Q&A by Jeffrey Palermo – 4.81 / 5.00
  • Total views (live + on-demand, as of Feb 15) - 58,300

Behind The Scenes: You

I wrote up a behind the scenes at mvcConf post after mvcConf 1, and am working on the same thing for this event. It's easy to focus on the technologies (breakout sessions using Live Meeting, live video using Silverlight Smooth Streaming, etc.) and how things were coordinated behind the scenes, but the real driving force behind this was the community:

The community showed up to the conference in a big way

You registered early, you showed up, and you participated (over 1500 tweets during the conference).

Community speakers stepped up to present

Of 27 sessions, only 7 had Microsoft participation. We had an open call for speakers, and accepted every submission. When people noticed that there were topic gaps in the session lineup, they volunteered additional sessions, and they were all added. We had a wide variety of content, including what's working for you in your shipping applications, the open source projects you're leading, etc.

Behind The Scenes: The Core Team

I described the history of mvcConf in my mvcConf 1 wrapup - it grew out of the C4MVC (Community For MVC) meetings, run by Eric Hexter and Javier Lozano. I've joined in as an mvcConf organizer because I think it's one of the most valuable ways I could be spending my time (a Microsoft Community PM focused on MVC), because I think it's a great effort I want to be a part of, and because - as a Microsoft employee - I can make some connections and facilitate getting things done (like lining up ASP.NET product team speakers and working with Channel 9) that are a little harder to do from the outside. We've been having regular, late night Skype meetings and epic weekend e-mail threads to get this planned out. It's been great working with such a dedicated, smart team to get this all put together.

During the conference, Javier and I were in the Channel 9 studios to keep things running and facilitate the live video stream. Eric Hexter ran the Live Meeting tracks from Austin, aided by a group of volunteers including (let me know if I miss anyone):

Behind The Scenes: Hanselminutes Interview

Scott Hanselman shrugged off pneumonia to recorded a podcast with Javier and me last week, discussing how the conference was run and where it could go in the future.

Download / Listen to the show:

Hanselminutes 253: Organizing your own Virtual Technical Conference - mvcConf Post-Mortem

Sessions Videos

All the sessions were recorded at 1280x720 (HD 720p) and are available in the following places:

The Channel 9 site offers a lot of formats - including WMV (high and low), MP4 (high and low), MP3, and Silverlight Smooth Streaming - as well as comments and an RSS feed. If you're watching using the Silverlight player and having trouble with the Smooth Streaming playing at low quality, you can try refreshing the page, or try the player on the mvcConf site - it overrides the Smooth Streaming to always play the high quality video, so the code should be readable.

Eric Sowell (@mallioch) stepped up to coordinate the session videos for all the Live Meeting sessions. That's no small feat - he followed up with all the presenters to get their Camtasia recordings for over 20 sessions, figured out backup plans when recordings weren't available, coordinated a group of volunteer editors, and made sure they all got turned over to Nic at Channel 9 for upload. We had most of them up within a week of the conference, and the final one just went up this morning.

Here are links to the individual session videos on Channel 9:

You can subscribe to the RSS feed here: http://channel9.msdn.com/Series/mvcConf/RSS

You can use my PowerShell downloader script to grab a local copy of all the session videos.

Keynote

Scott Guthrie kicked off the event with a great keynote. When we talked about the keynote before the event - and the informed, engaged people that attended mvcConf 1 - we agreed that an informal Ask The Gu talk would work great here. He split the one hour talk in half, starting with a look at how MVC fits in with the Microsoft web stack, a recap on the release cycles to date, and a look at where it's going. After that, we opened it up to a 30 minute Q&A period over Twitter. I was frantically scanning the Twitter stream, typing the questions in to our "teleprompter" (actually a laptop with WordPad hooked up to a big LCD screen).

 

Note: The Channel 9 video player is embeddable, so you can embed these talks in other web pages.

Channel 9

I've mentioned Chanel 9 over and over, so it should be clear that this event really wouldn't have been anywhere near what it was without their support. I've been working with Nic Fillingham (@nicfill) since right after mvcConf 1 wrapped up to figure out how we could pull this off. He, and the whole Channel 9 studios team have been extremely accommodating every step of the way (including support from Dan Fernandez and Jeff Sandquist). Some of the complications we worked through:

  • The studio was undergoing a major renovation that wrapped up the week before the conference. It was touch and go up until the end to see if it would be ready.
  • Channel 9 normally works on events run by people who know what they're doing, with things like "schedules" and "budgets." This event was way out of the standard way they handle things, and they were incredibly flexible and helpful every step of the way.

Live Meeting works well for individual breakout sessions, but has a hard limit of 1250 attendees per session. Working out a hybrid model with Channel 9 was essential here, giving us the best of both scaling opportunities:

  • Live video for the (anticipated) most popular tracks gave us virtually unlimited viewer scale - we could support tons of viewers without requiring any software other than Silverlight
  • Live Meeting gave us breadth scale, enabling us to support a lot of concurrent sessions with a huge variety of topics, adding new tracks as necessary

Here are some pictures from the studio:

Tweets

Twitter was a big part of this conference - more so than most conferences since it was completely virtual. We had a dedicated @mvcConf twitter account which made announcements (leading up to the conference, announcing the sessions during the conference, and giving status updates on videos after the conference). We used Twitter to take questions for the live video sessions (including half of the keynote, as mentioned above), and we also used Twitter to watch for any problems - potential video issues, Live Meeting difficulties, etc.

I ran The Archivist during the event to capture the complete tweet stream, running searches on both #mvcconf and @mvcconf. You can see that it was pretty busy throughout the day.

mvcConf Tweet Stream

Some favorite Tweets from the day:

@Fr3gU: Man, my brains are exploding from all the awesome information about ASP.NET MVC on #mvcConf. Luckily the sessions are being recorded.

@frank_meola: Got some great ideas from #mvcconf. I could taste the excitement all the way on the other coast. Mmmm.... bacon-y.

@vanderleidotnet: I'm impressed how #mvcconf is produced and coordinated. Thanks guys, some technical communities should learn something about this kindness.

@bmartin_us: mvcConf was INCREDIBLE! Thanks guys! #mvcconf

Sponsors

A free, community run event like this truly wouldn't have been possible without some sponsor support - just paying for the live video cost several thousand dollars, we had travel costs, etc., that had to be covered.

Our Partner Sponsors for the event were Microsoft and Umbraco. We'd like to give a big thanks to Umbraco for covering the cost of live video. You guys rock!

 

We had great support from several other sponsors, contributing financially as well as via design help (NimblePros), Camtasia licenses for all sponsors (TechSmith), etc.

     

Please take some time to thank our sponsors! It's not just nice, it's a good way to help make sure mvcConf 3 happens. :-)

Learn ASP.NET MVC 3 with the MVC Music Store tutorial

Now is a great time to learn ASP.NET MVC. ASP.NET MVC 3 combined with NuGet have made the start-to-finish process of building out a website a lot simpler. If you’d like to see what’s new in ASP.NET MVC 3 and NuGet, or if you’ve never done ASP.NET MVC development, I think the MVC Music Store is a great place to start.

The first release of MVC Music Store came out last May. I wrapped up a major update last October, and released a full rewrite on the day MVC 3 went live. Here’s an overview of what’s changed since the previous release:

  • All views are using the new Razor engine
  • Views demonstrate the use of Razor Layouts (rather than the MasterPages in the previous version)
  • Data access using Entity Framework Code-First (rather than the EF Database First approach in the previous releases)
  • Use of NuGet to install and configure the Entity Framework Code-First library
  • Added coverage of ViewBag, so the tutorial demonstrates use of both ViewBag and ViewModels to pass view-specific information
  • Using jQuery and the MVC 3 unobtrusive Ajax features for all client side scripting (previously used both jQuery and Microsoft AJAX)
  • Fixed some bugs and tricky parts based on thousands of previous downloads

You can read through the tutorial online on the ASP.NET website starting here: http://www.asp.net/mvc/tutorials/mvc-music-store-part-1

You can download all the materials for the tutorial from http://mvcmusicstore.codeplex.com, including:

  • 150 page PDF e-book tutorial with tons of screenshots and code samples
  • Assets to build out a working site – images, CSS, and a database stocked with music
  • The completed project so you can check against it if you’re having trouble
  • Tons and tons of screenshots to guide you through every step

Mvc Music Store - MVC 3

Mvc Music Store - MVC 3

 

Mvc Music Store - MVC 3

Mvc Music Store - MVC 3

The tutorial walks through the following topics:

  1. Overview and File->New Project
  2. Controllers
  3. Views (using Razor)
  4. Models and Data Access (using Entity Framework Code-First, installed via NuGet)
  5. Edit Forms and Templating
  6. Using Data Annotations for Model Validation
  7. Membership and Authorization
  8. Shopping Cart with Ajax Updates
  9. Registration and Checkout
  10. Final Updates to Navigation and Site Design, Conclusion

As before, everything’s under friendly licenses - the source is available under Ms-PL license, and the tutorial is under Creative Commons Attribution license. The data for the application is based on the Chinook database, which is also under Ms-PL license. The code repository uses Mercurial, and pull requests are welcome.

If you have comments or run into trouble, the best place to get help is on the Discussions board for the project on CodePlex. If you problems with the code that you think need to be fixed, please use the Issue Tracker on CodePlex – that drove a lot of the changes features for this release.

If you’re looking for a shorter, simpler tutorial to get started, check out the introductory MVC Movie Application tutorial, with code samples in both C# and VB.NET.

Top 10 reasons to get excited about mvcConf (the Virtual ASP.NET MVC Conference) on February 8, 2011

mvcConf is a free, all day community run virtual conference on 2/8/2011. If you haven’t registered yet, grab one of the last remaining tickets quick – they’re going fast!

Here are the top 10 reasons to get excited about mvcConf:

  1. It’s free
  2. An outstanding lineup of community presentations in three simultaneous tracks (interactive sessions via LiveMeeting)
  3. An awesome series of presentations from the product team, including:
    • Keynote by Scott Guthrie
    • Phil Haack on NuGet
    • Steve Sanderson on the great MvcScaffolding system he and Scott Hanselman have been cooking up
    • Brad Wilson on Advanced MVC 3
  4. We’ll be live streaming the Microsoft speakers from  the newly renovated Channel 9 studios, which means
    • Lots more space for more attendees this time
    • Great quality video
    • Live, smooth streaming video so you can rewind and catch parts if miss a bit due to “too much awesomeness” overload
  5. On demand video with no downtime after the event – we’ll keep the smooth streaming player running after the event until the on-demand videos go live
  6. Great variety of sessions focused on hard-core MVC development, but with some sprinklings of related tools like WebMatrix, IIS Express, WCF (with Glenn Block), and lots more
  7. Supporting jQuery project – we’re donating a portion of the proceeds to the jQuery project
  8. Awesome sponsors – financial and technical support (including expenses like live video streaming) has been covered by great sponsors, like Umbraco, Microsoft, telerik, DevExpress, NimblePros, and TechSmith.
  9. Great community involvement – one of the best features of the first mvcConf was the backchannel communication in the IRC rooms and via Twitter. This is a great opportunity to mingle with some of the top developers, community leaders, and the ASP.NET product team.
  10. Did I mention it’s free?

After registering, why not read more about how we ran the first mvcConf (July 2010), and check out some of last years’ session recordings (lo-fi recordings last year, this years’ recordings will be high quality thanks to a donation from TechSmith).

Posted by Jon Galloway | 3 comment(s)
Filed under:

Downloading a local NuGet repository with PowerShell

Update: This is now available as a NuGet package - NuGet.Downloader.  

Background

NuGet is a great way to add packages - libraries, content, and other dependencies - to your applications. It shipped with ASP.NET MVC 3 and WebMatrix, but you can use it with any .NET application type.

One of the best features of NuGet is that it runs on a feed, so package owners can publish new updates at any time. However, that can be a challenge, for a few reasons:

  1. If you want to develop but don't have access to the feed - e.g. working offline, or with spotty internet - you can't install or update your packages
  2. If you're doing a presentation and for whatever reason don't have access to the NuGet feed, your presentation flops
  3. If you're doing a presentation, a new release of a package can break your entire demo
  4. Development shops with build processes and controlled software package version migrations may want to have their developers pull from a local feed of approved packages

Last November, I headed out to India for a week of Web Camps. The first three motivations listed above came into play, and I was very happy to find that a post I'd recently read by Steve Michelotti titled Create a FULL Local NuGet Repository with PowerShell did just what I wanted - downloaded a local copy of all the NuGet packages to a folder. That's great, because NuGet lets you use a folder path as a repository, so having a local copy of all the NuGet packages means I can switch between the live feed and my local cache as desired.

A few things have changed since then:

  1. The NuGet feed structure has gone through a few changes which break Steve's script. One of the biggest changes is that the feed is broken into pages, so it currently gives you only the first 100 packages per request.
  2. The NuGet feed has grown quite a bit - a good thing, but enough so that I don't want to blindly pull the whole feed on a whim anymore.

An Updated NuGet Getter Script

I've been testing out a script since mid-December which has a bunch of additional features:

  • It follows redirects, so it should work regardless of where the feed moves
  • It handles paging over the OData feed
  • It's got an option to only get the latest release of each package - this is getting to be a bigger deal as packages continue to release new versions
  • It's got an option to skip downloads if you've already got a package
  • It's got an option to only get the "top x packages" by download count - again, a useful feature as the feed grows
  • It displays download progress, using a fancy progress bar if the environment supports it

How To Use

The easiest way to use the following script (included at the end of this post) is to open it in the PowerShell ISE (Integrated Scripting Environment). It's installed with PowerShell - did you know you had a PowerShell editor/debugger? If you're running Windows 7 (like the smart developer I know you are), just tap the Windows key and type "powershell" - you should see "Windows PowerShell ISE" show up in your Programs list.

Paste in the code, save it if you'd like, and hit F5 to run it.

2011-02-02 16h21_46

When you're done, you'll see the packages saved in your local folder. The default folder is in your profile's documents / LocalNuGet.

LocalNuGet - Folder

You can also just paste this into the  Package Manager Console, but you won't get any visual feedback.

LocalNuGet - PM Console

Using the Local Repository

Here's how to add that directory as one of the repositories NuGet can pull from. First, bring up the Package Manager Settings by clicking the icon to the right of the Package Source dropdown.

NuGet Package Manager Settings

Then just give your package source a name and fill in the folder path as the source, as shown below.

Local NuGet - Adding a package source

Now you can toggle the NuGet Package Source dropdown to pull from your Local repository whenever you want, or you can specify the source (using the full path) in the Get-Package command using the -Source parameter, e.g.

PM> Get-Package -Source "c:\users\jon\Documents\LocalNuGet"

You can read more on the Get-Package parameters in the NuGet documentation.

Next Steps

I've been thinking about turning this into a NuGet package, so I could just grab the package, run a command, and have a local package source. Thoughts?

The Script

Posted by Jon Galloway | 17 comment(s)
Filed under: ,
More Posts