Wednesday, September 21, 2011

jQuery UI Frame Dialog - Loading Pane–Revisited

Demo

It’s been awhile since I modified the jQuery UI Frame Dialog plugin to include a loading image/css to display while the iFrame’s content is loaded.  My original post is located here.

I’ve noticed (so have others here, here, etc…) that the iFrame’s content is requested multiple times.  If you’re interest in the reasons why the iFrame’s content is loaded multiple times, you can read about it here and here.  I’ve modified the plugin to avoid the multiple loads issue.  The modified JavaScript file can be downloaded by viewing source on the demo page here.

Again, I’ve tried to contact the original jQuery UI Frame Dialog’s author; however I’ve been unsuccessful.  So, rather than take ownership of the plugin, I’ve modified the version number with a .# extension that will serve as the version number of my modifications.  So, this specific version of the plugin has a file name of: jquery-framedialog-1.1.2.1.js.

I’ve tested the modified plugin on IE 8/9, Firefox 6.0.2, and Chrome 14.0.835.163 and it appears to be avoiding the multiple load issue.

Thanks for reading…

Demo

Friday, August 12, 2011

HttpPostedFile.FileName Beware…

Browser issues – you’ve gotta love them… 

Here’s the scenario…

We have an application that allows users to upload spreadsheets.  We parse the data in the spreadsheets to create new spreadsheets, save input to a data store, and a bunch of other useful functions.  Once the application was deployed, we started to get bug/issue reports on how the uploads were failing.  Typical user feedback: ‘…the Web site isn’t working;’ ‘…the uploading my database feature is broken;’ ‘…why can’t the Web site do it like Facebook?’  You get the idea…
We narrowed it down to an IE issue.  Most of the users were using IE8, while the developers were using Chrome, Firefox, and IE9.  Of course, the file upload and resulting file parsing was working fine for the developers and testers.  Why aren’t the users using Chrome, Firefox, IE9, Safari, etc…?  Well, because they are users Open-mouthed smile  Seriously though, the client’s organization is using IE8, so that’s what we should have used when developing and testing…

Continuing on…We couldn’t replicate the issue using IE9 in IE8 or IE7 mode; however, the bug/issue reports kept piling in…

Luckily, someone had an old VM with XP and IE8 installed.  So, we did a quick test using IE8, and sure enough, the ugly bug revealed itself.  Here’s a screenshot of what the YSOD could possibly look like (the paths and other revealing info is modified here, so the need for ‘possibly’).


Beyond the browser issue frustration, we couldn’t walk the code with VS2010, because the XP/IE8 VM did not have VS2010 installed.

What it all narrowed down to was how browsers offer up the file name (via HttpPostedFile.FileName property). All browsers (Chrome, FF, IE9, ...) but IE8- (IE8, 7, 6, ...) report ONLY the file name, while IE8- reports the fully qualified path on the client’s machine. The Fully Qualified Path (FQP) is the key here. Also, in IE9 in IE8 mode, the HttpPostedFile.FileName reports what IE9 would report and not IE8 (nice!).

The following is a snippet of the existing code (attachmentPath is the directory where the file will be saved to on the Server):

var fileName = Request.Files[i].FileName;
var filepath = Path.Combine(attachmentPath, fileName);

Do you see the issue? Well, when testing in all browsers but IE8-, this will work fine. However, in IE8-, the aforementioned snippet will result with a filepath of something like the following:

c:\directoryToStoreUploadedFiles\C:\Documents and Settings\xyz123\Desktop\ie8_testing.txt

while we are expecting the following:

c:\directoryToStoreUploadedFiles\ie8_testing.txt

So, make sure to parse out the file name correctly using the System.IO.Path.GetFileName() method. This method will return ONLY to file name (removing the directory path if it pre-pended).

The revised code snippet will work for all browsers:

var postedFile = Request.Files[i];
var fileName = Path.GetFileName(postedFile.FileName);
var filepath = Path.Combine(attachmentPath, fileName);

Now, we will always get what we are expecting.

If we would have looked at the MSDN documentation for the HttpPostedFile class (who does that??) - HttpPostedFile.FileName – we would have found the following documentation for the FileName property:

HttpPostedFile.FileName Property

Gets the fully qualified name of the file on the client.

Of course it does!?!? Not when the user is using Chrome, Firefox, IE9, or probably any other browser.

Simple solution, yet very difficult to track down. Something you may want to file away in your toolbox...

Thanks for reading…

Monday, May 16, 2011

NBuilder Extensions–US Address Randomizer– Make EF Code First Drop Database Less Painful

Have you used Entity Framework 4.1 Code First?  Specifically, have you used EF Code First with ASP.NET MVC 3 and MvcScaffolding?  If you have, you’ve felt the pain associated with adding properties to your model class, re-generating the code, and the framework requiring dropping of your database table and all the data that the table contains.  I’ve heard that Microsoft is planning of a solution to this, but in the meantime, we’re stuck with it…

A couple months ago, a colleague of mine recommended that I try out NBuilder.

NBuilder makes the aforementioned EF Code First pains suck less.  Less meaning that the pains still suck, but they are more tolerable.  If you’re not familiar with NBuilder, the NBuilder Website describes NBuilder as the following:

“Through a fluent, extensible interface, NBuilder allows you to rapidly create test data, automatically assigning values to properties and public fields that are of type of the built in .NET data types (e.g. ints and strings). NBuilder allows you to override for properties you are interested in using lambda expressions.”

That is exactly what it is.  But, how does it help EF Code First dropping tables requirement suck less?  Well, you can create an database initializer class that derives from DropCreateDatabaseIfModelChanges<T>, where T is your DbContext class, that contains a Seed method that will insert data into your data tables.  More on this later…  If you’re lost and/or not familiar with any of these terms (with the exception of NBuilder), I recommend that you check out Steve Sanderson’s Mix 11 cast: Scaffolding – ASP.NET, NuGet, Entity Framework Code First and More.

BTW, NBuilder is available via NuGet.

NBuilder contains facilities to randomly generate all kinds of data and data types including primitive types, phone numbers, date and time, first name, last name, addresses, etc... NBuilder also contains address randomizers; however, the randomizer supporting US addresses is not quite as useful as the randomizer for UK addresses.  Therefore, I created a class to generate more useful US addresses.  Below is a class snippet for this US address randomizer:

UsAddressRandomizer

using System.Collections.Generic;
using FizzWare.NBuilder.Generators;

namespace FizzWare.NBuilder
{
    public class UsAddressRandomizer
    {
        private static readonly IRandomGenerator Generator = new RandomGenerator();

        #region Data Generation
        private static readonly List<UsAddressFake> States =
            new List<UsAddressFake>
                {
                    new UsAddressFake { StateName = "Alaska", StateCode = "AK", ZipRangeBegin = 99500, ZipRangeEnd = 99999},
                    new UsAddressFake { StateName = "Alabama", StateCode = "AL", ZipRangeBegin = 35000, ZipRangeEnd = 36999},
                    new UsAddressFake { StateName = "Arkansas", StateCode = "AR", ZipRangeBegin = 71600, ZipRangeEnd = 72999},
                    new UsAddressFake { StateName = "Arizona", StateCode = "AZ", ZipRangeBegin = 85000, ZipRangeEnd = 86599},
                    new UsAddressFake { StateName = "California", StateCode = "CA", ZipRangeBegin = 90000, ZipRangeEnd = 96699},
                    new UsAddressFake { StateName = "Colorado", StateCode = "CO", ZipRangeBegin = 80000, ZipRangeEnd = 81699},
                    new UsAddressFake { StateName = "Connecticut", StateCode = "CT", ZipRangeBegin = 6000, ZipRangeEnd = 6999},
                    new UsAddressFake { StateName = "Delaware", StateCode = "DE", ZipRangeBegin = 19700, ZipRangeEnd = 19999},
                    new UsAddressFake { StateName = "Florida", StateCode = "FL", ZipRangeBegin = 32000, ZipRangeEnd = 34999},
                    new UsAddressFake { StateName = "Georgia", StateCode = "GA", ZipRangeBegin = 30000, ZipRangeEnd = 31999},
                    new UsAddressFake { StateName = "Hawaii", StateCode = "HI", ZipRangeBegin = 96700, ZipRangeEnd = 96899},
                    new UsAddressFake { StateName = "Iowa", StateCode = "IA", ZipRangeBegin = 50000, ZipRangeEnd = 52899},
                    new UsAddressFake { StateName = "Idaho", StateCode = "ID", ZipRangeBegin = 83200, ZipRangeEnd = 83899},
                    new UsAddressFake { StateName = "Illinois", StateCode = "IL", ZipRangeBegin = 60000, ZipRangeEnd = 62999},
                    new UsAddressFake { StateName = "Indiana", StateCode = "IN", ZipRangeBegin = 46000, ZipRangeEnd = 47999},
                    new UsAddressFake { StateName = "Kansas", StateCode = "KS", ZipRangeBegin = 66000, ZipRangeEnd = 67999},
                    new UsAddressFake { StateName = "Kentucky", StateCode = "KY", ZipRangeBegin = 40000, ZipRangeEnd = 42799},
                    new UsAddressFake { StateName = "Louisiana", StateCode = "LA", ZipRangeBegin = 70000, ZipRangeEnd = 71499},
                    new UsAddressFake { StateName = "Massachusetts", StateCode = "MA", ZipRangeBegin = 1000, ZipRangeEnd = 2799},
                    new UsAddressFake { StateName = "Maryland", StateCode = "MD", ZipRangeBegin = 20600, ZipRangeEnd = 21999},
                    new UsAddressFake { StateName = "Maine", StateCode = "ME", ZipRangeBegin = 3900, ZipRangeEnd = 4999},
                    new UsAddressFake { StateName = "Michigan", StateCode = "MI", ZipRangeBegin = 48000, ZipRangeEnd = 49999},
                    new UsAddressFake { StateName = "Minnesota", StateCode = "MN", ZipRangeBegin = 55000, ZipRangeEnd = 56799},
                    new UsAddressFake { StateName = "Missouri", StateCode = "MO", ZipRangeBegin = 63000, ZipRangeEnd = 65899},
                    new UsAddressFake { StateName = "Mississippi", StateCode = "MS", ZipRangeBegin = 38600, ZipRangeEnd = 39799},
                    new UsAddressFake { StateName = "Montana", StateCode = "MT", ZipRangeBegin = 59000, ZipRangeEnd = 59999},
                    new UsAddressFake { StateName = "North Carolina", StateCode = "NC", ZipRangeBegin = 26900, ZipRangeEnd = 28999},
                    new UsAddressFake { StateName = "North Dakota", StateCode = "ND", ZipRangeBegin = 58000, ZipRangeEnd = 58899},
                    new UsAddressFake { StateName = "Nebraska", StateCode = "NE", ZipRangeBegin = 68000, ZipRangeEnd = 69399},
                    new UsAddressFake { StateName = "New Hampshire", StateCode = "NH", ZipRangeBegin = 3000, ZipRangeEnd = 3999},
                    new UsAddressFake { StateName = "New Jersey", StateCode = "NJ", ZipRangeBegin = 7000, ZipRangeEnd = 8999},
                    new UsAddressFake { StateName = "New Mexico", StateCode = "NM", ZipRangeBegin = 87000, ZipRangeEnd = 88499},
                    new UsAddressFake { StateName = "Nevada", StateCode = "NV", ZipRangeBegin = 88900, ZipRangeEnd = 89899},
                    new UsAddressFake { StateName = "New York", StateCode = "NY", ZipRangeBegin = 500, ZipRangeEnd = 6399},
                    new UsAddressFake { StateName = "Ohio", StateCode = "OH", ZipRangeBegin = 43000, ZipRangeEnd = 45999},
                    new UsAddressFake { StateName = "Oklahoma", StateCode = "OK", ZipRangeBegin = 73000, ZipRangeEnd = 74999},
                    new UsAddressFake { StateName = "Oregon", StateCode = "OR", ZipRangeBegin = 97000, ZipRangeEnd = 97999},
                    new UsAddressFake { StateName = "Pennsylvania", StateCode = "PA", ZipRangeBegin = 15000, ZipRangeEnd = 19699},
                    new UsAddressFake { StateName = "Rhode Island", StateCode = "RI", ZipRangeBegin = 2800, ZipRangeEnd = 2999},
                    new UsAddressFake { StateName = "South Carolina", StateCode = "SC", ZipRangeBegin = 29000, ZipRangeEnd = 29999},
                    new UsAddressFake { StateName = "South Dakota", StateCode = "SD", ZipRangeBegin = 57000, ZipRangeEnd = 57799},
                    new UsAddressFake { StateName = "Tennessee", StateCode = "TN", ZipRangeBegin = 37000, ZipRangeEnd = 38599},
                    new UsAddressFake { StateName = "Texas", StateCode = "TX", ZipRangeBegin = 75000, ZipRangeEnd = 79999},
                    new UsAddressFake { StateName = "Utah", StateCode = "UT", ZipRangeBegin = 84000, ZipRangeEnd = 84799},
                    new UsAddressFake { StateName = "Vermont", StateCode = "VT", ZipRangeBegin = 5000, ZipRangeEnd = 5999},
                    new UsAddressFake { StateName = "Virginia", StateCode = "VA", ZipRangeBegin = 22000, ZipRangeEnd = 24699},
                    new UsAddressFake { StateName = "Washington", StateCode = "WA", ZipRangeBegin = 98000, ZipRangeEnd = 99499},
                    new UsAddressFake { StateName = "Wisconsin", StateCode = "WI", ZipRangeBegin = 53000, ZipRangeEnd = 54999},
                    new UsAddressFake { StateName = "West Virginia", StateCode = "WV", ZipRangeBegin = 24700, ZipRangeEnd = 26899},
                    new UsAddressFake { StateName = "Wyoming", StateCode = "WY", ZipRangeBegin = 82000, ZipRangeEnd = 83199}
                };

        private static readonly List<string> Cities =
            new List<string>
                {
                    "Abington",
                    "Acton",
                    "Acushnet",
                    "Adams",
                    "Agawam",
                    "Alford",
                    "Amesbury",
                    "Amherst",
                    "Andover",
                    "Aquinnah",
                    "Arlington",
                    "Ashburnham",
                    "Ashby",
                    "Ashfield",
                    "Ashland",
                    "Athol",
                    "Attleboro",
                    "Auburn",
                    "Avon",
                    "Ayer",
                    "Barnstable",
                    "Barre",
                    "Becket",
                    "Bedford",
                    "Belchertown",
                    "Bellingham",
                    "Belmont",
                    "Berkley",
                    "Berlin",
                    "Bernardston",
                    "Beverly",
                    "Billerica",
                    "Blackstone",
                    "Blandford",
                    "Bolton",
                    "Boston",
                    "Bourne",
                    "Boxborough",
                    "Boxford",
                    "Boylston",
                    "Braintree",
                    "Brewster",
                    "Bridgewater",
                    "Brimfield",
                    "Brockton",
                    "Brookfield",
                    "Brookline",
                    "Buckland",
                    "Burlington",
                    "Cambridge",
                    "Canton",
                    "Carlisle",
                    "Carver",
                    "Charlemont",
                    "Charlton",
                    "Chatham",
                    "Chelmsford",
                    "Chelsea",
                    "Cheshire",
                    "Chester",
                    "Chesterfield",
                    "Chicopee",
                    "Chilmark",
                    "Clarksburg",
                    "Clinton",
                    "Cohasset",
                    "Colrain",
                    "Concord",
                    "Conway",
                    "Cummington",
                    "Dalton",
                    "Danvers",
                    "Dartmouth",
                    "Dedham",
                    "Deerfield",
                    "Dennis",
                    "Dighton",
                    "Douglas",
                    "Dover",
                    "Dracut",
                    "Dudley",
                    "Dunstable",
                    "Duxbury",
                    "East Bridgewater",
                    "East Brookfield",
                    "East Longmeadow",
                    "Eastham",
                    "Easthampton",
                    "Easton",
                    "Edgartown",
                    "Egremont",
                    "Erving",
                    "Essex",
                    "Everett",
                    "Fairhaven",
                    "Fall River",
                    "Falmouth",
                    "Fitchburg",
                    "Florida",
                    "Foxborough",
                    "Framingham",
                    "Franklin",
                    "Freetown",
                    "Gardner",
                    "Georgetown",
                    "Gill",
                    "Gloucester",
                    "Goshen",
                    "Gosnold",
                    "Grafton",
                    "Granby",
                    "Granville",
                    "Great Barrington",
                    "Greenfield",
                    "Groton",
                    "Groveland",
                    "Hadley",
                    "Halifax",
                    "Hamilton",
                    "Hampden",
                    "Hancock",
                    "Hanover",
                    "Hanson",
                    "Hardwick",
                    "Harvard",
                    "Harwich",
                    "Hatfield",
                    "Haverhill",
                    "Hawley",
                    "Heath",
                    "Hingham",
                    "Hinsdale",
                    "Holbrook",
                    "Holden",
                    "Holland",
                    "Holliston",
                    "Holyoke",
                    "Hopedale",
                    "Hopkinton",
                    "Hubbardston",
                    "Hudson",
                    "Hull",
                    "Huntington",
                    "Ipswich",
                    "Kingston",
                    "Lakeville",
                    "Lancaster",
                    "Lanesborough",
                    "Lawrence",
                    "Lee",
                    "Leicester",
                    "Lenox",
                    "Leominster",
                    "Leverett",
                    "Lexington",
                    "Leyden",
                    "Lincoln",
                    "Littleton",
                    "Longmeadow",
                    "Lowell",
                    "Ludlow",
                    "Lunenburg",
                    "Lynn",
                    "Lynnfield",
                    "Malden",
                    "Manchester-by-the-Sea",
                    "Mansfield",
                    "Marblehead",
                    "Marion",
                    "Marlborough",
                    "Marshfield",
                    "Mashpee",
                    "Mattapoisett",
                    "Maynard",
                    "Medfield",
                    "Medford",
                    "Medway",
                    "Melrose",
                    "Mendon",
                    "Merrimac",
                    "Methuen",
                    "Middleborough",
                    "Middlefield",
                    "Middleton",
                    "Milford",
                    "Millbury",
                    "Millis",
                    "Millville",
                    "Milton",
                    "Monroe",
                    "Monson",
                    "Montague",
                    "Monterey",
                    "Montgomery",
                    "Mount Washington",
                    "Nahant",
                    "Nantucket",
                    "Natick",
                    "Needham",
                    "New Ashford",
                    "New Bedford",
                    "New Braintree",
                    "New Marlborough",
                    "New Salem",
                    "Newbury",
                    "Newburyport",
                    "Newton",
                    "Norfolk",
                    "North Adams",
                    "North Andover",
                    "North Attleborough",
                    "North Brookfield",
                    "North Reading",
                    "Northampton",
                    "Northborough",
                    "Northbridge",
                    "Northfield",
                    "Norton",
                    "Norwell",
                    "Norwood",
                    "Oak Bluffs",
                    "Oakham",
                    "Orange",
                    "Orleans",
                    "Otis",
                    "Oxford",
                    "Palmer",
                    "Paxton",
                    "Peabody",
                    "Pelham",
                    "Pembroke",
                    "Pepperell",
                    "Peru",
                    "Petersham",
                    "Phillipston",
                    "Pittsfield",
                    "Plainfield",
                    "Plainville",
                    "Plymouth",
                    "Plympton",
                    "Princeton",
                    "Provincetown",
                    "Quincy",
                    "Randolph",
                    "Raynham",
                    "Reading",
                    "Rehoboth",
                    "Revere",
                    "Richmond",
                    "Rochester",
                    "Rockland",
                    "Rockport",
                    "Rowe",
                    "Rowley",
                    "Royalston",
                    "Russell",
                    "Rutland",
                    "Salem",
                    "Salisbury",
                    "Sandisfield",
                    "Sandwich",
                    "Saugus",
                    "Savoy",
                    "Scituate",
                    "Seekonk",
                    "Sharon",
                    "Sheffield",
                    "Shelburne",
                    "Sherborn",
                    "Shirley",
                    "Shrewsbury",
                    "Shutesbury",
                    "Somerset",
                    "Somerville",
                    "South Hadley",
                    "Southampton",
                    "Southborough",
                    "Southbridge",
                    "Southwick",
                    "Spencer",
                    "Springfield",
                    "Sterling",
                    "Stockbridge",
                    "Stoneham",
                    "Stoughton",
                    "Stow",
                    "Sturbridge",
                    "Sudbury",
                    "Sunderland",
                    "Sutton",
                    "Swampscott",
                    "Swansea",
                    "Taunton",
                    "Templeton",
                    "Tewksbury",
                    "Tisbury",
                    "Tolland",
                    "Topsfield",
                    "Townsend",
                    "Truro",
                    "Tyngsborough",
                    "Tyringham",
                    "Upton",
                    "Uxbridge",
                    "Wakefield",
                    "Wales",
                    "Walpole",
                    "Waltham",
                    "Ware",
                    "Wareham",
                    "Warren",
                    "Warwick",
                    "Washington",
                    "Watertown",
                    "Wayland",
                    "Webster",
                    "Wellesley",
                    "Wellfleet",
                    "Wendell",
                    "Wenham",
                    "West Boylston",
                    "West Bridgewater",
                    "West Brookfield",
                    "West Newbury",
                    "West Springfield",
                    "West Stockbridge",
                    "West Tisbury",
                    "Westborough",
                    "Westfield",
                    "Westford",
                    "Westhampton",
                    "Westminster",
                    "Weston",
                    "Westport",
                    "Westwood",
                    "Weymouth",
                    "Whately",
                    "Whitman",
                    "Wilbraham",
                    "Williamsburg",
                    "Williamstown",
                    "Wilmington",
                    "Winchendon",
                    "Winchester",
                    "Windsor",
                    "Winthrop",
                    "Woburn",
                    "Worcester",
                    "Worthington",
                    "Wrentham",
                    "Yarmouth"
                };

        private static readonly List<string> Streets =
            new List<string>
                {
                    "107th Street",
                    "10th Avenue",
                    "10th Street",
                    "11th Avenue",
                    "11th Street",
                    "12th Avenue",
                    "12th Street",
                    "137th Street",
                    "13th Street",
                    "14th Road",
                    "14th Street",
                    "17th Street",
                    "181st Street",
                    "18th Street",
                    "19th Street",
                    "1st Avenue",
                    "1st Street",
                    "23rd Street",
                    "25th Street",
                    "2nd Avenue",
                    "2nd Street",
                    "30th Avenue",
                    "31st Street",
                    "33rd Street",
                    "34th Avenue",
                    "35th Avenue",
                    "35th Street",
                    "36th Street",
                    "37th Avenue",
                    "39th Avenue",
                    "3rd Avenue",
                    "3rd Street",
                    "45th Avenue",
                    "47th Avenue",
                    "4th Avenue",
                    "4th Street",
                    "51st Avenue",
                    "52 Chambers Street",
                    "52nd Street",
                    "5th Avenue",
                    "5th Street",
                    "68th Street",
                    "6th Avenue",
                    "6th Street",
                    "76th Street",
                    "77th Street",
                    "78th Street",
                    "79th Street",
                    "7th Avenue",
                    "7th Avenue South",
                    "7th Street",
                    "80th Street",
                    "81st Street",
                    "82nd Street",
                    "83rd Street",
                    "84th Street",
                    "85th Street",
                    "86th Street",
                    "87th Street",
                    "88th Street",
                    "8th Avenue",
                    "8th Street",
                    "90th Avenue",
                    "90th Street",
                    "9th Avenue",
                    "9th Street",
                    "Abingdon Square",
                    "Adelphi Street",
                    "Albemarle Road",
                    "Albemarle Terrace",
                    "Alexander Avenue",
                    "Amboy Road",
                    "Amity Street",
                    "Amsterdam Avenue",
                    "Andrews Avenue",
                    "Argyle Road",
                    "Arthur Kill Road",
                    "Ashland Place",
                    "Astor Place",
                    "Atlantic Avenue",
                    "Available",
                    "Avenue A",
                    "Avenue Of Americas",
                    "Avenue Of The Americas",
                    "Avenue Z",
                    "Bainbridge Street",
                    "Baltic Street",
                    "Bank Street",
                    "Barclay Street",
                    "Barrow Street",
                    "Baxter Street",
                    "Beach 124th Street",
                    "Beach Street",
                    "Beaver Road",
                    "Beaver Street",
                    "Beck Street",
                    "Bedford Avenue",
                    "Bedford Street",
                    "Beekman Place",
                    "Beekman Street",
                    "Bergen Street",
                    "Berkeley Place",
                    "Bethune Street",
                    "Bicycle Racks",
                    "Bleecker Street",
                    "Bond Street",
                    "Boston Road",
                    "Botanical Garden",
                    "Bowery Street",
                    "Bowling Green",
                    "Bowne Street",
                    "Bridge Street",
                    "Brielle Avenue",
                    "Brighton Beach Avenue",
                    "Broad Street",
                    "Broadway",
                    "Brooklyn Heights",
                    "Broome Street",
                    "Buckingham Road",
                    "Bushwick Avenue",
                    "Cadman Plaza West",
                    "Calyer Street",
                    "Cambridge Place",
                    "Canal Street",
                    "Carlton Avenue",
                    "Carroll Gardens Historic Distr",
                    "Carroll Place",
                    "Carroll Street",
                    "Central  Park West",
                    "Central Avenue",
                    "Central Park  West",
                    "Central Park North",
                    "Central Park South",
                    "Central Park West",
                    "Centre Street",
                    "Chambers Street",
                    "Charles Street",
                    "Charlton Street",
                    "Chatham Square",
                    "Chauncey Street",
                    "Cheever Place",
                    "Chelsea Square Park",
                    "Christopher Street",
                    "Chruch Street",
                    "Church Avenue",
                    "Church Street",
                    "City College",
                    "City Hall",
                    "Clark Street",
                    "Classon Avenue",
                    "Clay Avenue",
                    "Clermont Avenue",
                    "Clifton Place",
                    "Clinton Avenue",
                    "Clinton Street",
                    "Clove Road",
                    "Coenties Slip",
                    "College Place",
                    "Columbia Heights",
                    "Columbia Place",
                    "Columbia Street",
                    "Columbus Avenue",
                    "Columbus Street",
                    "Commerce Street",
                    "Congress Street",
                    "Convent Avenue",
                    "Cooper Square",
                    "Cornelia Street",
                    "Cornell Cemetery",
                    "Court Place",
                    "Court Square",
                    "Court Street",
                    "Cranberry Street",
                    "Cropsey Avenue",
                    "Crosby Street",
                    "Croton Aqueduct",
                    "Cumberland Street",
                    "Dalny Road",
                    "Dawson Street",
                    "Dean Street",
                    "Decatur Street",
                    "Degraw Street",
                    "Dekalb Avenue",
                    "Ditmars Boulevard",
                    "Ditmas Avenue",
                    "Dorchester Avenue",
                    "Doris Freedman Plaza",
                    "Doughty Street",
                    "Dover Street",
                    "Downing Street",
                    "Drinking Fountain",
                    "Duane Street",
                    "Dyre Avenue",
                    "Eagle Street",
                    "East 103rd Street",
                    "East 104th Street",
                    "East 106th Street",
                    "East 10th Street",
                    "East 110th Street",
                    "East 11th Street",
                    "East 121st Street",
                    "East 125th Street",
                    "East 12th Street",
                    "East 136th Street",
                    "East 139th Street",
                    "East 13th Street",
                    "East 140th Street",
                    "East 141st Street",
                    "East 14th Street",
                    "East 151st Street",
                    "East 156th Street",
                    "East 15th Street",
                    "East 161st Street",
                    "East 166th Street",
                    "East 16th Street",
                    "East 179th Street",
                    "East 17th Street",
                    "East 17th Stret",
                    "East 18th Street",
                    "East 19th Street",
                    "East 20th Street",
                    "East 21st Street",
                    "East 22nd Street",
                    "East 23rd Street",
                    "East 24th Street",
                    "East 29th Street",
                    "East 32nd Street",
                    "East 34th Street",
                    "East 35th Street",
                    "East 36th Street",
                    "East 3rd Street",
                    "East 41st Street",
                    "East 42nd Street",
                    "East 43rd Street",
                    "East 44th Street",
                    "East 45th Street",
                    "East 46th Street",
                    "East 48th Street",
                    "East 49th Street",
                    "East 4th Street",
                    "East 50th Street",
                    "East 52nd Street",
                    "East 53rd Street",
                    "East 54th Street",
                    "East 55th Street",
                    "East 56th Street",
                    "East 57th Street",
                    "East 58th Street",
                    "East 59th Street",
                    "East 60th Street",
                    "East 61st Street",
                    "East 62nd Street",
                    "East 63rd Street",
                    "East 64th Street",
                    "East 65th Street",
                    "East 66th Street",
                    "East 67th Street",
                    "East 68th Street",
                    "East 69th Street",
                    "East 6th Street",
                    "East 70th Street",
                    "East 71st Street",
                    "East 72nd Street",
                    "East 73rd Street",
                    "East 74th Street",
                    "East 75th Street",
                    "East 76th Street",
                    "East 77th Street",
                    "East 78th Street",
                    "East 79th Street",
                    "East 7th Street",
                    "East 80th Street",
                    "East 81st Street",
                    "East 82nd Street",
                    "East 83rd Street",
                    "East 84th Street",
                    "East 85th Street",
                    "East 86th Street",
                    "East 87th Street",
                    "East 88th Street",
                    "East 89th Street",
                    "East 8th Street",
                    "East 90th Street",
                    "East 91st Street",
                    "East 92dnd Street",
                    "East 92nd Street",
                    "East 93rd Street",
                    "East 94th Street",
                    "East 95th Street",
                    "East 96th Street",
                    "East 9th Street",
                    "East Broadway",
                    "East End Avenue",
                    "East Fordham Road",
                    "East Tremont Avenue",
                    "Eastern Parkway",
                    "Edgecombe Avenue",
                    "Eldridge Street",
                    "Elizabeth Street",
                    "Elk Street",
                    "Emmons Avenue",
                    "Ericsson Place",
                    "Everit Street",
                    "Exchange Place",
                    "Faile Street",
                    "Federal Plaza",
                    "Fenimore Street",
                    "Fifth Avenue",
                    "Fillmore Street",
                    "Fiske Place",
                    "Flagg Court",
                    "Flagg Place",
                    "Flatbush Avenue",
                    "Flatbush Malls",
                    "Foley Square",
                    "Fordham University",
                    "Forest Avenue",
                    "Fort Greene Avenue",
                    "Fort Greene Place",
                    "Fort Totten Avenue",
                    "Fort Washington Avenue",
                    "Franklin Avenue",
                    "Franklin Street",
                    "Frederick Douglas Boulevard",
                    "Front Street",
                    "Fulton Ferry Streets",
                    "Fulton Fish Market",
                    "Fulton Landing",
                    "Fulton Street",
                    "Gansevoort Street",
                    "Garden Place",
                    "Garfield Place",
                    "Gates Avenue",
                    "Gateway Boulevard",
                    "Gay Street",
                    "Grace Court",
                    "Grace Court Alley",
                    "Grace Street",
                    "Gracie Mansion",
                    "Gramercy Park East",
                    "Gramercy Park North",
                    "Gramercy Park South",
                    "Gramercy Park West",
                    "Gramercy Place",
                    "Grand Army Plaza",
                    "Grand Avenue",
                    "Grand Central Terminal",
                    "Grand Concourse",
                    "Grand Street",
                    "Grant Street",
                    "Great Jones Street",
                    "Great Kills Road",
                    "Green Wood Cemetery",
                    "Greene Avenue",
                    "Greene Street",
                    "Greenpoint Avenue",
                    "Greenport Road",
                    "Greenwich Avenue",
                    "Greenwich Mews",
                    "Greenwich Street",
                    "Greenwich Village",
                    "Grove Court",
                    "Grove Street",
                    "Guernsey Street",
                    "Hall Street",
                    "Hamilton Avenue",
                    "Hamilton Place",
                    "Hamilton Terrace",
                    "Hanover Square",
                    "Hanson Place",
                    "Harrison Street",
                    "Heberton Avenue",
                    "Henderson Place",
                    "Henry Hudson Parkway",
                    "Henry Street",
                    "Heritage Trail",
                    "Heritage Trails",
                    "Hester Street",
                    "Hewitt Place",
                    "Hicks Street",
                    "High Bridge Aqueduct",
                    "Horatio Street",
                    "Howard Street",
                    "Hoyt Street",
                    "Hubert Street",
                    "Hudson Street",
                    "Hunts Lane",
                    "Hunts Lane Alley",
                    "Hydrants",
                    "Hylan Boulevard",
                    "Independence Avenue",
                    "Irving Place",
                    "Jackson Avenue",
                    "Jackson Street",
                    "Jamaica Avenue",
                    "James Street",
                    "Jane Street",
                    "Jay Street",
                    "Jefferson Avenue",
                    "Jerome Avenue",
                    "John Street",
                    "Jones Street",
                    "Joralemon Street",
                    "Jumel Terrace",
                    "Kane Street",
                    "Kelly Street",
                    "Kenmore Terrace",
                    "Kent Street",
                    "King Street",
                    "Kings Highway",
                    "Kingsbridge Terrace",
                    "Lafayette Avenue",
                    "Lafayette Street",
                    "Laguardia Airport",
                    "Laight Street",
                    "Lefferts Avenue",
                    "Lefferts Homestead",
                    "Lefferts Place",
                    "Lefferts Road",
                    "Lenox Avenue",
                    "Leonard Street",
                    "Leroy Street",
                    "Lewis Avenue",
                    "Lexington Avenue",
                    "Liberty Street",
                    "Lighting",
                    "Lincoln Avenue",
                    "Lincoln Place",
                    "Lincoln Road",
                    "Linwood Street",
                    "Lispenard Street",
                    "Little Bay",
                    "Little Neck Parkway",
                    "Little West 12th Street",
                    "Livingston Street",
                    "Lorillard Snuff Mill",
                    "Lorimer Street",
                    "Louis Street",
                    "Love Lane",
                    "Macdonough Street",
                    "Macdougal Alley",
                    "Macdougal Street",
                    "Macon Street",
                    "Madison Avenue",
                    "Madison Street",
                    "Maiden Lane",
                    "Main Street",
                    "Malcolm X Boulevard",
                    "Manhattan Avenue",
                    "Maple Street",
                    "Marcus Garvey Boulevard",
                    "Marcus Garvey Park",
                    "Marcy Avenue",
                    "Marlborough Road",
                    "Maujer Street",
                    "Mcdonald Avenue",
                    "Mercer Street",
                    "Middagh Street",
                    "Midwood Street",
                    "Milligan Place",
                    "Milton Avenue",
                    "Milton Street",
                    "Mitchell Place",
                    "Monroe Place",
                    "Montague Street",
                    "Montague Terrace",
                    "Montgomery Place",
                    "Morris Avenue",
                    "Morris Park Avenue",
                    "Morton Street",
                    "Mott Street",
                    "Mount Morris Park West",
                    "Mulry Square",
                    "Murray Street",
                    "Narrows Avenue",
                    "Nassau Street",
                    "Nevins Street",
                    "New Dorp Lane",
                    "New Lots Avenue",
                    "Newkirk Avenue",
                    "Nixon Avenue",
                    "Noble Street",
                    "Norfolk Street",
                    "Norman Avenue",
                    "North Moore Street",
                    "Northern Boulevard",
                    "Nostrand Avenue",
                    "Nycta Subway Entrance",
                    "Oak Street",
                    "Ocean Avenue",
                    "Ocean Parkway",
                    "Ogden Avenue",
                    "Old Fulton Street",
                    "Old Slip",
                    "Oliver Street",
                    "Orange Street",
                    "Pacific Street",
                    "Park Avenue",
                    "Park Avenue South",
                    "Park Place",
                    "Park Row",
                    "Park Row North",
                    "Patchin Place",
                    "Pearl Street",
                    "Peck Slip",
                    "Pedestrian Ramps",
                    "Pell Mansion",
                    "Perry Street",
                    "Pierrepont Place",
                    "Pierrepont Street",
                    "Pike Street",
                    "Pineapple Street",
                    "Plaque",
                    "Plaques",
                    "Plaza Street",
                    "Plaza Street West",
                    "Polhemus Place",
                    "Polhemus Street",
                    "Pomander Walk",
                    "Poplar Street",
                    "Powells Cove Boulevard",
                    "President Street",
                    "Prince Street",
                    "Prospect Park West",
                    "Putnam Avenue",
                    "Quincy Street",
                    "Reade Street",
                    "Recycling Cans",
                    "Remsen Avenue",
                    "Remsen Street",
                    "Revere Place",
                    "Richmond Hill Road",
                    "Richmond Road",
                    "Richmond Street",
                    "Richmond Terrace",
                    "Riverdale Avenue",
                    "Riverside Drive",
                    "Riverside Drive West",
                    "Riverside Park",
                    "Rockefeller Center",
                    "Rockefeller Plaza",
                    "Rockland Avenue",
                    "Rogers Avenue",
                    "Roosevelt Avenue",
                    "Roosevelt Island",
                    "Rufus King Manor",
                    "Rugby Road",
                    "Rutherford Place",
                    "Rutland Road",
                    "Ryerson Street",
                    "Sailors' Snug Harbor",
                    "Schermerhorn Street",
                    "Sedgwick Avenue",
                    "Sequine Avenue",
                    "Sheridan Square",
                    "Shore Road",
                    "Sidney Place",
                    "Simpson Street",
                    "Smith Street",
                    "Sniffen Court",
                    "Snug Harbor",
                    "Snug Harbor Cultural Center",
                    "Snyder Avenue",
                    "South 9th Street",
                    "South Elliott Place",
                    "South Oxford Street",
                    "South Portland Avenue",
                    "South Portland Street",
                    "South Street",
                    "South Street Seaport",
                    "South William Street",
                    "Southern Boulevard",
                    "Spring Street",
                    "St. Alban's Place",
                    "St. Andrew's Plaza",
                    "St. Ann's Avenue",
                    "St. Felix Street",
                    "St. James Place",
                    "St. Johns Place",
                    "St. John's Place",
                    "St. Lukes Place",
                    "St. Luke's Place",
                    "St. Mark Avenue",
                    "St. Marks Avenue",
                    "St. Marks Place",
                    "St. Mark's Place",
                    "St. Nicholas Avenue",
                    "St. Nicholas Terrace",
                    "St. Patrick's Place",
                    "St. Paul's Avenue",
                    "State Street",
                    "Sterling Place",
                    "Sterling Street",
                    "Stone Street",
                    "Stratford Road",
                    "Street Signs",
                    "Strong Place",
                    "Stuyvesant Avenue",
                    "Stuyvesant Square",
                    "Stuyvesant Street",
                    "Sullivan Street",
                    "Sutphin Boulevard",
                    "Sutton Place",
                    "Sycamore Avenue",
                    "Sylvan Terrace",
                    "Thomas Street",
                    "Thompson Street",
                    "Throop Avenue",
                    "Times Square",
                    "Tompkins Avenue",
                    "Tompkins Place",
                    "Trinity Place",
                    "Tudor City",
                    "Tudor City Place",
                    "Union Hall Street",
                    "Union Square West",
                    "Union Street",
                    "University Place",
                    "Van Cortlandt Mansion",
                    "Vandam Street",
                    "Vanderbilt Avenue",
                    "Varick Street",
                    "Verandah Place",
                    "Verdi Square",
                    "Vernon Boulevard",
                    "Vesey Street",
                    "Vestry Street",
                    "Village Road South",
                    "Walker Street",
                    "Wall Street",
                    "Warren Place",
                    "Warren Street",
                    "Warsoff Place",
                    "Washington Avenue",
                    "Washington Mews",
                    "Washington Place",
                    "Washington Square North",
                    "Washington Square South",
                    "Washington Square West",
                    "Washington Street",
                    "Water Street",
                    "Watts Street",
                    "Wave Hill",
                    "Waverly Avenue",
                    "Waverly Place",
                    "Webster Avenue",
                    "Weirfield Street",
                    "West 101st Street",
                    "West 102nd Street",
                    "West 105th Street",
                    "West 106th Street",
                    "West 107th Street",
                    "West 108th Street",
                    "West 109th Street",
                    "West 10th Street",
                    "West 114th Street",
                    "West 115th Street",
                    "West 119th Street",
                    "West 11th Street",
                    "West 120th Street",
                    "West 121st Street",
                    "West 122nd Street",
                    "West 123rd Street",
                    "West 125th Street",
                    "West 126th Street",
                    "West 127th Street",
                    "West 128th Street",
                    "West 129th Street",
                    "West 12th Street",
                    "West 130th Street",
                    "West 134th Street",
                    "West 135th Street",
                    "West 138th Street",
                    "West 139th Street",
                    "West 13th Street",
                    "West 140th Street",
                    "West 141st Street",
                    "West 142nd Street",
                    "West 143rd Street",
                    "West 144th Street",
                    "West 145th Street",
                    "West 148th Street",
                    "West 14th Street",
                    "West 150th Street",
                    "West 151st Street",
                    "West 155th Street",
                    "West 156th Street",
                    "West 160th Street",
                    "West 162nd Street",
                    "West 16th Street",
                    "West 17th Street",
                    "West 18th Street",
                    "West 19th Street",
                    "West 20th Street",
                    "West 21st Street",
                    "West 22nd Street",
                    "West 23rd Street",
                    "West 247th Street",
                    "West 249th Street",
                    "West 24th Street",
                    "West 252nd Street",
                    "West 25th Street",
                    "West 261st Street",
                    "West 26th Street",
                    "West 27th Street",
                    "West 29th Street",
                    "West 31st Street",
                    "West 33rd Street",
                    "West 34th Street",
                    "West 37th Street",
                    "West 3rd Street",
                    "West 40th Street",
                    "West 41st Street",
                    "West 42nd Street",
                    "West 43rd Street",
                    "West 44th Street",
                    "West 45th Street",
                    "West 46th Street",
                    "West 47th Street",
                    "West 48th Street",
                    "West 49th Street",
                    "West 4th Street",
                    "West 50th Street",
                    "West 51st Street",
                    "West 52nd Street",
                    "West 53rd Street",
                    "West 54th Street",
                    "West 55th Street",
                    "West 56th Street",
                    "West 57th Street",
                    "West 58th Street",
                    "West 59th Street",
                    "West 5th Street",
                    "West 61st Street",
                    "West 63rd Street",
                    "West 64th Street",
                    "West 65th Street",
                    "West 66th Street",
                    "West 67th Street",
                    "West 68th Street",
                    "West 69th Street",
                    "West 70th Street",
                    "West 71st Street",
                    "West 72nd Street",
                    "West 73rd Street",
                    "West 74th Street",
                    "West 75th Street",
                    "West 76th Street",
                    "West 77th Street",
                    "West 78th Street",
                    "West 79th Street",
                    "West 80th Street",
                    "West 81st Street",
                    "West 82nd Street",
                    "West 83rd Street",
                    "West 84th Street",
                    "West 85th Street",
                    "West 86th Street",
                    "West 87th Street",
                    "West 88th Street",
                    "West 89th Street",
                    "West 8lst Street",
                    "West 8th Street",
                    "West 90th Street",
                    "West 91st Street",
                    "West 92nd Street",
                    "West 93rd Street",
                    "West 94th Street",
                    "West 95th Street",
                    "West 96th Street",
                    "West 9th Street",
                    "West Broadway",
                    "West Drive",
                    "West End Avenue",
                    "West Houston Street",
                    "West Kingsbridge Road",
                    "West Street",
                    "Westervelt Avenue",
                    "Westminster Road",
                    "White Street",
                    "William Street",
                    "Willoughby Avenue",
                    "Willoughby Street",
                    "Willow Place",
                    "Willow Street",
                    "Wilson Avenue",
                    "Winant Place",
                    "Woodrow Road",
                    "Woodycrest Avenue",
                    "Wooster Street",
                    "Worth Street",
                    "Wyckoff Street",
                    "York Avenue"
                };
        #endregion Data Generation

        public static string Street()
        {
            return Streets[Generator.Next(0, Streets.Count - 1)];
        }

        public static string City()
        {
            return Cities[Generator.Next(0, Cities.Count - 1)];
        }

        public static string StateName()
        {
            return States[Generator.Next(0, States.Count - 1)].StateName;
        }

        public static string StateCode()
        {
            return States[Generator.Next(0, States.Count - 1)].StateCode;
        }

        public static string Zip()
        {
            return Zip(false);
        }

        public static string Zip(bool withExtension)
        {
            var address = States[Generator.Next(0, States.Count - 1)];
            return Zip(withExtension, address.ZipRangeBegin, address.ZipRangeEnd);
        }

        private static string Zip(bool withExtension, int zipRangeBegin, int zipRangeEnd)
        {
            var zip = Generator.Next(zipRangeBegin, zipRangeEnd);
            var pre = string.Format("{0:d5}", zip);

            if (!withExtension) return pre;

            var post = Zip(false);
            return string.Format("{0}-{1}", pre, post.Substring(0, 4));
        }

        public static string FullAddress()
        {
            return FullAddress(false);
        }

        public static string FullAddress(bool withExtension)
        {
            var address = States[Generator.Next(0, States.Count - 1)];

            return string.Format("{0} {1}, {2}, {3} {4}",
                Generator.Next(1, 10000),
                Street(),
                City(),
                address.StateName,
                 Zip(withExtension, address.ZipRangeBegin, address.ZipRangeEnd));
        }

        public static string PhoneNumber()
        {
            return GetRandom.Usa.PhoneNumber();
        }

        public static string SocialSecurityNumber()
        {
            return GetRandom.Usa.SocialSecurityNumber();
        }

        internal class UsAddressFake
        {
            internal string StateName { get; set; }
            internal string StateCode { get; set; }
            internal int ZipRangeBegin { get; set; }
            internal int ZipRangeEnd { get; set; }
        }
    }
}
You can use this class in your project, or create a separate project and add the class to the project and import the project reference into you project containing your DbContext class.

Let’s say that you’ve created a Visual Studio solution with an ASP.NET MVC 3 application, EF Code First and using MvcScaffolding – similar to Steve Sanderson’s Mix 11 cast: Scaffolding – ASP.NET, NuGet, Entity Framework Code First and More.  Your MVC 3 project contains the following two Model classes and DbContext classs:

using System;
using System.Collections.Generic;

namespace MvcCodeFirstSqlCompact.Models
{
    public class Dinner
    {
        public int DinnerId { get; set; }
        public string Title { get; set; }
        public DateTime EventDate { get; set; }
        public string Address { get; set; }
        public string HostedBy { get; set; }
        public string UrlLink { get; set; }

        public virtual ICollection<Rsvp> Rsvps { get; set; }
    }
}

namespace MvcCodeFirstSqlCompact.Models
{
    public class Rsvp
    {
        public int RsvpId { get; set; }
        public string AttendeeEmail { get; set; }

        public int DinnerId { get; set; }
        public virtual Dinner Dinner { get; set; }
    }
}

namespace MvcCodeFirstSqlCompact.Models
{
    public class MvcCodeFirstSqlCompactContext : DbContext
    {
        public MvcCodeFirstSqlCompactContext()
        {
            Database.SetInitializer(new MvcCodeFirstSqlCompactInitializer());
        }

        public DbSet<MvcCodeFirstSqlCompact.Models.Dinner> Dinners { get; set; }

        public DbSet<MvcCodeFirstSqlCompact.Models.Rsvp> Rsvps { get; set; }
    }
}
Notice how the DbContext constructor sets the initializer to MvcCodeFirstSqlCompactInitializer.  This is the class that will insert data into your data source once a change in made to one of your model classes and requires database tables to be dropped.  The following snippet is the code for the MvcCodeFirstSqlCompactInitializer:

using System;
using System.Data.Entity;
using FizzWare.NBuilder;
using FizzWare.NBuilder.Generators;

namespace MvcCodeFirstSqlCompact.Models
{
    public class MvcCodeFirstSqlCompactInitializer : DropCreateDatabaseIfModelChanges<MvcCodeFirstSqlCompactContext>
    {
        protected override void Seed(MvcCodeFirstSqlCompactContext context)
        {
            var uniqueGenerator = new UniqueRandomGenerator();
            var generator = new RandomGenerator();

            var dinners = Builder<Dinner>.CreateListOfSize(10).WhereAll()
                .Have(d => d.Title = string.Format("{0} {1} Dinner", uniqueGenerator.Next(0, 100), GetRandom.UK.County()))
                .And(d => d.Address = UsAddressRandomizer.FullAddress(true))
                .And(d => d.HostedBy = string.Format("{0} {1}", GetRandom.FirstName(), GetRandom.LastName()))
                .And(d => d.EventDate = uniqueGenerator.Next(new DateTime(2010, 1, 1), new DateTime(2011, 5, 4)))
                .And(d => d.UrlLink = "http://" + GetRandom.Url())
                .Build();

            foreach (var dinner in dinners)
                context.Dinners.Add(dinner);

            var rsvps = Builder<Rsvp>.CreateListOfSize(300).WhereAll()
                .Have(d => d.AttendeeEmail = GetRandom.Email())
                .And(d => d.Dinner = dinners[generator.Next(1, 10)])
                .Build();

            foreach (var rsvp in rsvps)
                context.Rsvps.Add(rsvp);
        }
    }
}
Notice how this class derives from DropCreateDatabaseIfModelChanges<T>, where T is your DbContext class?  This class will execute the code in the overridden the Seed method when EF Code First needs to create OR recreate the data source.  In the above scenario, the Seed method uses the NBuilder and UsAddressRandomizer facilities to generate data and insert the data into your data tables. 

No more manual data insertions into your database once EF Code First creates/recreates the database.  Not as sweet as EF Code First combined with MvcScaffolding, but pretty sweet nonetheless?

All pains aside, I’m really impressed with EF Code First and liking it more and more everyday.  That said, I hope this post and NBuilder helps your avoid some of the pain associated with EF Code First.

Again, if you are unfamiliar with any of the previous concepts and technologies, I highly recommend that you take a look at Steve Sanderson’s Mix 11 cast - Scaffolding – ASP.NET, NuGet, Entity Framework Code First and More, his blog series -  Scaffold your ASP.NET MVC 3 project with the MvcScaffolding package, and explore the usefulness of NBuilder.

Thanks for reading…

Tuesday, March 22, 2011

Updated - MvcContrib UI Extensions - Themed Grid & Menu

After a comment on by blog here, I have updated the MvcContrib UI Extensions source code, the sample MVC3 Web application (both source and demo), and deployed a new NuGet package to the public NuGet feed.  Here are the links:
Thanks for reading...

Tuesday, March 15, 2011

Another Entity Framework 4 Repository & Unit of Work Solution–Intro and Part 4: ASP.NET MVC 3 Project

This is Part 4 in a series of posts that walk through the process of implementing a solution that separates concerns into specific behaviors using the Entity Framework 4 and the Repository and Unit of Work Patterns.

Below is the series outline; again, this is Part 4.
Now on to Part 4… Open up the Chinook solution in Visual Studio. Let’s do a little solution organization.  Create the following three solution folders by right-clicking the solution file, selecting ‘Add,’ and then selecting ‘New Solution Folder.’ image
  • Core
  • Infrastructure
  • Web
Place the Chinook.Core project into the Core Solution Folder and place the other two projects (Chinook.Data.EF and Chinook.Infrastructure) into the Infrastructure Solution Folder.  The Web Solution Folder will contain our MVC Web application project.  Let’s do that now… Right-click the Web Solution Folder.  Click 'Add’ –> ‘New Project…’ image Next, create an ASP.NET MVC 3 Web Application and name is ‘Chinook.Web’ and click ‘OK.’ image On the next screen, select ‘Internet Application,’ the ‘Razor’ View engine, and click ‘OK’ image Right-click the new ‘Chinook.Web’ Application Project and select ‘Set As Startup Project.’  The solution structure should now look similar to the following: image Add the following References to the ‘Chinook.Web’ Project and then build the solution. image In the description of this post, it states that we are going to use StructureMpa as our DI container.  We are going to get StructureMap via NuGet.  Assuming you have NuGet installed, select the Chinook.Web project, open the ‘Package Manager Console,’ and type the following command:
PM> Install-Package StructureMap
This will install StructureMap and register any assemblies with the Chinook.Web project.  Once the NuGet command is executed, the NuGet Package Manager Console should echo the following: image Go ahead and build the solution. Next, add the the new StructureMap reference to both the Chinook.Data.EF and Chinook.Infrastructure projects and rebuild the solution. Again, this series assumes that you have all the necessary tools (NuGet, POCO templates, etc…) installed with Visual Studio and that you are somewhat familiar with StructureMap. Now, remember the two files (EFRepositoryRegistry.cs.txt and ServicesRegistry.cs.txt) that the T4 templates generated for us in the previous post?  We are going to use those files to create our StructureMap registries.  The best way to do this is to create two new cs files in the respective projects, copy the code from the generated file, and paste it into these new code files.  I understand this is not idea (copy, paste, etc…); however, I didn’t want to limit our solution to StructureMap only, so we’ll just have to deal with the awkwardness for now.  So, create the following files and replace all the code in the new code file with the code in the associated generated file.
  • EFRepositoryRegistry.cs – in the Chinook.Data.EF project
    • EFRepositoryRegistry.cs.txt – generated file
  • ServicesRegistry.cs – in the Services directory within the Chinook.Implementation project
    • ServicesRegistry.cs.txt – generated file
Go ahead and build the solution again. Next, we are going to register our repositories, unit of work, and other dependencies (created earlier in a previous post) with StructureMap in our Chinook.Web project.  To do this, we are going to use ASP.NET MVC 3 IDependencyResolver – you can read about IDependencyResolver here and read the API docs here. Create a ‘Bootstrap’ directory in the Chinook.Web project and create the following two empty code/class files:
  • StructureMapContainerSetup.cs – make this class static
  • StructureMapDependencyResolver.cs
Now we are going to register the Registries created earlier in these ‘bootstrap’ files.  Since this series of posts is walk through on the process of setting up a solution for separation of concerns and not on the theory of such topics, the exercise of explaining the StructureMap registration is beyond the scope of this series.  Populate these newly created code files with the following content:
StructureMapDependencyResolver
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using StructureMap;

namespace Chinook.Web.Bootstrap
{
    public class StructureMapDependencyResolver : IDependencyResolver
    {
        private readonly IContainer _container;

        public StructureMapDependencyResolver(IContainer container)
        {
            _container = container;
        }

        #region Implementation of IDependencyResolver

        /// <summary>
        /// Resolves singly registered services that support arbitrary object creation.
        /// </summary>
        /// <returns>
        /// The requested service or object.
        /// </returns>
        /// <param name="serviceType">The type of the requested service or object.</param>
        public object GetService(Type serviceType)
        {
            var instance = _container.TryGetInstance(serviceType);

            if ((instance == null) && !serviceType.IsAbstract)
            {
                _container.Configure(c => c.AddType(serviceType, serviceType));
                instance = _container.TryGetInstance(serviceType);
            }
            return instance;
        }

        /// <summary>
        /// Resolves multiply registered services.
        /// </summary>
        /// <returns>
        /// The requested services.
        /// </returns>
        /// <param name="serviceType">The type of the requested services.</param>
        public IEnumerable<object> GetServices(Type serviceType)
        {
            return _container.GetAllInstances(serviceType).Cast<object>();
        }

        #endregion
    }
}
StructureMapContainerSetup
using System.Web.Mvc;
using Chinook.Data.EF;
using Chinook.Infrastructure.Services;
using StructureMap;

namespace Chinook.Web.Bootstrap
{
    public static class StructureMapContainerSetup
    {
        public static void Setup()
        {
            IContainer container = new Container(
                x =>
                    {
                        x.AddRegistry(new EFRepositoryRegistry());
                        x.AddRegistry(new ServicesRegistry());
                    }
                );

            DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
        }
    }
}
Now we are going to invoke the StructureMap registration bootstrapping code from the Application_Start method of the Global.asax.cs file.  Here’s the snippet:
protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    StructureMapContainerSetup.Setup();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}
Go ahead and build the solution again… We are now going to create a quick controller, view, and some supporting View Models that will give a simple example how to use all the code created in this series of posts.  For this part, go ahead and download the final solution.  Logically representing the code here will be difficult and would provide little value without context; therefore, download the final solution and review the code in the Chinook.Web project.  Here’s a quick list of the steps involved to generated the code samples:
  1. Create a ViewModel - AlbumGridItemViewModel.
  2. Create a IViewModelBuilder/ViewModelBuilder – IAlbumGridItemViewModelBuilder/AlbumGridItemViewModelBuilder.
  3. Create a new Controller - AlbumController.
  4. Use constructor injection to inject the ViewModelBuilder into the Controller -  IAlbumGridItemViewModelBuilder into the AlbumController.
  5. Create a View to represent a list of ViewModel items – Index – this is only a list of items; however, the process remains the same for all types of views.
  6. Register the IViewModelBuilder/ViewModelBuilder with StructureMap – using a similar pattern as the other DI registrations – a StructureMap Registry.
The resulting list generated in the sample code is not designed for performance (e.g. no paging, sorting, etc..).  In production, this type of code can and should be refactored.  That said, the key points throughout this series are the patterns used to create a solution based on separation of concerns – including the Repository and Unit of Work patterns and using StructureMap as a Dependency Injection container.

Thanks for reading…

Another Entity Framework 4 Repository & Unit of Work Solution–Intro and Part 3: Generated Code Review

This is Part 3 in a series of posts that walk through the process of implementing a solution that separates concerns into specific behaviors using the Entity Framework 4 and the Repository and Unit of Work Patterns.

Below is the series outline; again, this is Part 3.
Now on to Part 3… Open up the Chinook solution in Visual Studio.  Expand the Chinook.Core Project, expand the Domain directory, and then expand both the Domain.Poco.tt and Domain.Poco.Metadata.tt files.  You should see something like the following: image These child-files under the *.tt file are the code file generated by the T4 templates.  Go ahead an open the highlighted file – InvoiceLine.Metadata.cs and this file’s sister class file Invoice.cs (under the Domain.Poco.tt file).  The Invoice.cs file contains a POCO class for the Invoice entity of the EF data model (edmx), while the InvoiceLine.Metadata.cs contains the data annotations/metadata ‘buddy’ class for the sister POCO class (Invoice.cs).  That’s quite a mouthful, so take a bit of time and review the generated code. Okay, now expand the Domain and Services directories and the associated T4 template files within the Chinook.Core project.  You should have something similar to the following: image Open up the following Repository.Interface.tt child files.  Reference the code snippets below when reading the brief description of each file.
  • IReadOnlyRepository.cs
    • The IReadOnlyRepository is the base interface that all the entity specific interfaces inherit from.  The IReadOnlyRepository contains (you guessed it…Winking smile) read-only interfaces to the persistence layer.
  • IRepository.cs
    • The IRepository interface extends the IReadOnlyIRepository interface to include creating and deleting or entities.
    • The original intent of separating the IReadOnlyRepository and IRepository interfaces was that so POCO object backed by data views (VIEWs on a database) would not inherit creating and deleting functionality.
  • IUnitOfWork.cs
    • The IUnitOfWork interface handles all the transactions and changes needed to persist modifications to the persistence mechanism. 

IReadOnlyRepository.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Chinook.Core.Repository
{
    /// <summary>
    /// Generic Read-Only Repository Contract
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IReadOnlyRepository<t> where T : class
    {
        /// <summary>
        /// Gets an IQueryable sequence of entities of type T.
        /// </summary>
        /// <returns></returns>
        IQueryable<t> Queryable();

        /// <summary>
        /// Gets an IEnumerable sequence of all entites of type T.
        /// </summary>
        /// <returns></returns>
        IEnumerable<t> All();

        /// <summary>
        /// Get an IEnumerable sequence of entities of type T filtered on the @where predicate.
        /// </summary>
        /// <param name="where">The where predicate.</param>
        /// <returns></returns>
        IEnumerable<t> Find(Expression<func><t bool ,>> where);

        /// <summary>
        /// Gets a single entity in a sequence of entities of type T using the filtered @where predicate.
        /// </summary>
        /// <param name="where">The where predicate.</param>
        /// <returns></returns>
        T Single(Expression<func><t bool ,>> where);

        /// <summary>
        /// Gets the first entity in a sequence of entities of type T using the filtered @where predicate.
        /// </summary>
        /// <param name="where">The where predicate.</param>
        /// <returns></returns>
        T First(Expression<func><t bool ,>> where);

        /// <summary>
        /// Gets a single entity (or default of entity of type T) in a sequence of entities of type T using the filtered @where predicate.
        /// </summary>
        /// <param name="where">The where predicate.</param>
        /// <returns></returns>
        T SingleOrDefault(Expression<func><t bool ,>> where);

        /// <summary>
        /// Gets a first entity (or default entity of type T) in a sequence of entities of type T using the filtered @where predicate.
        /// </summary>
        /// <param name="where">The where predicate.</param>
        /// <returns></returns>
        T FirstOrDefault(Expression<func><t bool ,>> where);
    }
}

IRepository.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Chinook.Core.Repository
{ 
    /// <summary>
    /// Generic Repository Contract.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IRepository<t> : IReadOnlyRepository<t> where T : class
    {
        /// <summary>
        /// Adds the specified entity to the respository of type T.
        /// </summary>
        /// <param name="entity">The entity to add.</param>
        void Add(T entity);

        /// <summary>
        /// Deletes the specified entity to the respository of type T.
        /// </summary>
        /// <param name="entity">The entity to delete.</param>
        void Delete(T entity);

        /// <summary>
        /// Attaches the specified entity to the respository of type T.
        /// </summary>
        /// <param name="entity">The entity to attach.</param>
        void Attach(T entity);
    }
}
IUnitOfWork.cs
namespace Chinook.Core.Repository
{ 
 /// <summary>
    /// Unit of Work Contract
    /// </summary>
    public interface IUnitOfWork
    {
        /// <summary>
        /// Commits the changes to the data store.
        /// </summary>
        void Commit();
    }
}
The other Repository interfaces are just POCO specific Repository interfaces – man, that sounds really redundant… The Services Interfaces – child-files of the Services.Interface.tt template are just empty service interfaces that you can add to as needed.  Like the Repository interfaces, each POCO has it’s own Service interface. Next, expand the Chinook.Infrastructure Project’s Services.Implementation.tt file.  The code files generated by this T4 template are concrete implementation class of the aforementioned Service interfaces.  There is a one-to-one relationship among the code generated interfaces to the code generated concrete implementations. Next, expand the Chinook.Data.EF Project’s Repository.Implementation.EF.tt file. image As you can see, there is pretty much a one-one-relationship among the interfaces generated in the Chinook.Core/Repository to the concrete implementations here.  Go ahead and spend some time looking over the generated files.  The implementation for each is straight forward. Beyond the Repository implementations, the following are notable files generated by the Repository.Implementation.EF.tt template:
  • IObjectContext
    • this is an interface that defines the contract used by the ObjectContextAdapter, the EFUnitOfWork, and ultimately the ObjectContext.
  • ObjectContextAdapter
    • this is a simple adapter class that wraps the Entity Framework’s ObjectContext object for use in the Repository/Unit of Work paradigm.  This class implements the IObjectContext contract.
  • RepositoryIQueryableExtensions
    • this class includes a single method: Include.  Include is an IQueryable(of T) extension method that affords the ‘Eager Loading’ functionality provided by the Entity Framework.  But, since our solution abstracts the Entity Framework, the EF ‘Eager Loading’ Include method is not available.  This extension method gives our solution the functionality back.  You may not realize this yet, but that is a really cool ‘feature!’
    • The implementation of this Include extension method was taken from the following article on MSDN: http://msdn.microsoft.com/en-us/ff714955.aspx – this is a great article and one that I got quite a few ideas for this series and solution.
Template Bonuses
Template Force Code (Re)Generation – or NOT
Of this six T4 templates included in the download, all but the Domain.Poco.tt contain the following settings:
// answers the question: Force generation of file even if the code file exists?
bool forceCodeGeneration = false;
As the name of the setting/variable and the associated comment suggests, this is an on/off switch for forcing code (re)generation.  The default for this setting is false, meaning that if code is regenerated, the existing code will NOT be overwritten.  So, let’s say that you create a custom email validator like the one in a previous post of mine - ASP.NET 3 Custom Validation.  You manually decorate a few POCO properties in the POCO ‘buddy’ classes – the one containing metadata and data annotations – with the new email validator (e.g. Required(ErrorMessage = “Email is Required”)].  You have client-side and server-side validation working like a charm.  Now, let’s say that your one or your database tables has changed and or you added a new table.  You are going to want to regenerate all the classes and interfaces that the T4 templates created for you.  No Problem!  If you have the forceCodeGeneration settings set to false, your manual code changes will NOT get overwrittenand that hard work of yours will not need to be redone, or at a minimum, merged from the files in you source control system.  You are using a source control system, aren’t you???
StructureMap configuration for Repositories and Services
If you’re reading this blog series, I’m sure you’re familiar with Dependency Injection (DI).  There are quite a few DI containers for .NET; however, my favorite is StructureMap.  Why is it my favorite?  Well, when I first endeavored on the DI/IOC concept, StructureMap is what those around me recommended.  I was not disappointed!  The documentation could be better – it’s a little out-of-date; however, the DI API for StructureMap is extremely easy to use and relatively easy to understand.  You will first need to overcome the DI/IOC paradigm challenges, but once the 'light goes on,’ you’ll wonder how you survived without it… Okay, back to the Bonuses…  Expand the Repository.Implementation.EF.tt and Service.Implementation.tt T4 templates.  Below are screenshots of the two T4 template generated outputs.  Notice the highlighted files… image image All four of these files contain StructureMap Dependency Injection registration code.  The files stating with __StructureMap.* contain ‘raw’ registration code that you can use however you’d like.  The other two files (EFRepositoryRegistry.cs.txt and ServicesRegistry.cs.txt) contain StructureMap Registry derived classes.  According to the StructureMap documentation, Registries are the recommended way to configure StructureMap:
“The Registry DSL is the recommended way to configure StructureMap, and creating Registry classes is the recommended way of using the Registry DSL.”

We will be using the code in these files in the next post in this series… Stay tuned…

In summary, we reviewed a few of the code files that the T4 templates generated, discussed how to NOT to overwrite your manual code changes to the generated files, and discovered how the T4 templates generate StuctureMap DI registration snippets and Registries for you.

In the next post in this series, we will put all the fruits of our labor (okay, the code generated labor) to use in an ASP.NET MVC 3 Web Application.

Thanks for reading…