Site Meter
 
 

MvcScaffolding: Standard Usage

This post is part of a series about the MvcScaffolding NuGet package:

  1. Introduction: Scaffold your ASP.NET MVC 3 project with the MvcScaffolding package
  2. This post: Standard usage: Typical use cases and options
  3. One-to-Many Relationships
  4. Scaffolding Actions and Unit Tests
  5. Overriding the T4 templates
  6. Creating custom scaffolders
  7. Scaffolding custom collections of files

This post describes some of the basic functionality you get with the MvcScaffolding package as soon as you install it. First, though, let’s explain a few core concepts. Don’t worry, there aren’t too many strange new concepts…

If this is the first time you’ve heard about MvcScaffolding, check out this other introductory post first.

What is a scaffolder?

A scaffolder is something that does scaffolding :) . Typically it consists of a PowerShell script that holds its logic, and a set of T4 templates that define the output it can produce, though you don’t need to know about how they work unless you want to make your own.

To see a list of available scaffolders, issue this command in the Package Manager Console:

Get-Scaffolder

image

Hopefully, your screen will be a little wider and you’ll actually be able to read the descriptions! Anyway, as you can see, scaffolders can live in NuGet packages and they have unique names like MvcScaffolding.RazorView. You could have lots of different scaffolders that produce views (e.g., you already have MvcScaffolding.AspxView too), and identify them by their unique name. For example, you could choose to scaffold an ASPX view as follows:

Scaffold MvcScaffolding.AspxView Index Team

Here, “Team” is the name of my model class (see the previous post for the steps to set up the project). Your model class might be Product or Customer or whatever. You can enter a fully-qualified type name, or just the unqualified name, and the scaffolder will search your referenced projects to find it.

Scaffolders can accept their own set of parameters.  In PowerShell, named parameters are introduced using a dash (“-“) characters, so to see a list of available parameters, enter text as far as the dash and then press TAB:

image

Some of those are specific to the scaffolder; others are common PowerShell parameters. I’ll explain what the scaffolder-specific ones do later.

What are “default scaffolders”?

You don’t want to keep typing out those long scaffolder names every time you want to use them (even with the tab-completion). Maybe you always want to use MvcScaffolding.RazorView by default for all views. Well, that’s exactly what defaults do.

To see what scaffolders are configured as defaults, enter the following command:

Get-DefaultScaffolder

image

As shown in the screenshot, default names are short, generic identifiers like Controller or Repository or View. That’s what makes it possible to enter “Scaffold Controller …” or “Scaffold View …” and not have to enter the full scaffolder name.

Interesting aside: when you first installed MvcScaffolding, it inspected your project and picked a default “View” scaffolder based on which view engine you appear to be using.

Default names are mapped onto full scaffolder names by means of an XML configuration file. You don’t need to see or edit the configuration file, though, because you can read it using Get-DefaultScaffolder, and write it using Set-DefaultScaffolder.

For example, to say that you want to generate ASPX views by default, enter the following:

Set-DefaultScaffolder View MvcScaffolding.AspxView

Now if you re-run Get-DefaultScaffolder, you’ll see that the name View resolves to MvcScaffolding.AspxView. Also, if you enter “Get-Scaffolder View”, you’ll see it returns information about the MvcScaffolding.AspxView scaffolder.

image

Note that when scaffolders call each other internally (e.g., the MvcScaffolding.Controller scaffolder internally calls Scaffold Repository … and Scaffold View …), they do so using the default names, not the full names. That means if you’ve configured some other default for View, it will get used by the Controller scaffolder automatically.

These defaults are stored on a per-project basis (so you can have different defaults for different projects), but you can also define solution-wide defaults by passing the “-SolutionWide” flag to Set-DefaultScaffolder.

Using the built-in scaffolders

Here’s what you can do with MvcScaffolding (and its parent package, T4Scaffolding) automatically:

Scaffold Controller <controllerNameOrModelType>

This produces an ASP.NET MVC controller for CRUD operations with an EF-code-first data context and views for Create, Details, Delete, Edit, and Index. Options include:

  • -ControllerName : Specify the name of the controller you want. If you’ve entered something that looks like a controller name, e.g., ProductsController or ProductController, we’ll use that name and go looking for a model class called Products or Product. If you enter something that looks like a model type, e.g., Product, we’ll look for that model and create you a controller called ProductsController.
  • -ModelType : By default we try to infer this from the controller name, but if you want your controllers and models to have totally unrelated names, you can specify a particular model type using this parameter. We’ll find any model class defined in your project or another project it references, but not in any external assembly.
  • -Project : Specify which ASP.NET MVC project the output goes into (you could have multiple such projects in your solution – by default we use the one specified by the “Default project” dropdown at the top of the Package Manager Console).
  • -CodeLanguage : Specify either “cs” or “vb” if you want. By default we use the same code language as your project. Theoretically you could pass “fsharp” or any other string for this parameter, but it would only work if the scaffolder could find a matching template.
  • -DbContextType : Specify the name of the database context class that should be generated or updated. By default, we use the name <yourProjectName>Context, e.g., SoccerSiteContext.
  • -Repository : This is a switch parameter, which means it doesn’t take any value. Just adding –Repository to the command line means that we’ll generate a repository class and interface, and the controller will do data access using that repository interface.
  • -Area : If you want the generated files to go into a specific ASP.NET MVC area, enter its name here. Note that you must have created that area already; the scaffolder doesn’t create areas automatically (yet).
  • -Layout : (Note: –MasterPage is a PowerShell alias for this parameter, so you can enter either name) If you want to use a specific Razor layout or ASPX Master Page, enter its virtual path here, e.g., “-Layout /Views/Shared/_SomeLayout.cshtml”. Otherwise, if you’re using Razor we’ll assume you want the default layout, and if you’re using ASPX we’ll look for a default Master Page (~/Views/Shared/Site.Master) or if not found produce a full HTML page (i.e., no master page).
  • -Force : By default, we don’t overwrite any files that already exist. If you do want to overwrite things, pass this switch.
  • -NoChildItems : If for some reason you only want to generate the controller class and don’t want any views, repositories, or data contexts, pass this switch.

In due course, we’ll add proper PowerShell-based documentation so you can get help on any specific scaffolder or parameter directly from the Package Manager Console.

Scaffold View <controllerName> <viewName>

This produces an empty view associated with the specified controller. Note that you should provide the short name for the controller, i.e., Products not ProductsController, as this is the name of the folder where the view goes. Also, you can specify:

  • -Template : Should be one of Create, Delete, Details, Edit, Index, or Edit. Instead of producing an empty view, we’ll use the specified template
  • -ModelType : Creates a strongly-typed view for the chosen model type. If you’re scaffolding a Create, Delete, Details, Edit, or Index view, the output will take account of the properties exposed by your model type.

Other parameters include: –Project, –Area, –Layout, –CodeLanguage, –Force. See above for information about these.

Scaffold Views <modelType>

This produces all of the standard CRUD views: Create, Delete, Details, Edit, and Index. Internally, the “controller” scaffolder calls this unless you’ve passed the –NoChildItems switch. It takes the same parameters as the “view” scaffolder.

Scaffold DbContext <modelType> <dbContextName>

This produces an Entity Framework Code First database context class for the given model type. If there’s already a database context class with matching name, we’ll simply add another DbSet<modelType>property to it without losing its existing properties. So, as you scaffold more models, your context will build up references to all the model types you’re persisting.

Other available parameters include:

  • -Folder : Forces the output to go into a specific folder relative to your project. By default, we use the /Models folder.
  • -Area : If you haven’t set a value for –Folder, this parameter populates –Folder using the ASP.NET MVC convention /Areas/<areaName>/Models.
  • Common ones such as –Project, –Force, and so on.
Scaffold Repository <modelType>

This produces a repository interface named after your model type (e.g., IProductRepository) along with an implementation that works using Entity Framework Code First. The repository exposes methods that get a specific model instance by primary key value, gets all model instances, adds a new model instance, and deletes a model instance. These operations don’t write to the database immediately – there’s also a “Save()” method which writes all the changes you made to the database.

Other parameters include:

  • -NoChildItems : Internally, the default repository scaffolder also calls “Scaffold DbContext …” to generate or update an underlying database context, which is what connects your application to the actual data access technology. If you don’t want to generate or update any database context, pass the –NoChildItems flag.
  • -Folder and –Area : These are passed on to the DbContext scaffolder (unless you pass the –NoChildItems flag, in which case the DbContext scaffolder won’t be called).
  • Common ones such as –Project, –Force, and so on.

Overriding the standard scaffolders with LINQ to SQL ones

To prove that this is an extensible system, I’ve created an experimental “LinqToSqlScaffolding” package that can replace the usual Entity Framework-powered “Repository” and “DbContext” scaffolders. To install it, enter the following into Package Manager Console:

Install-Package LinqToSqlScaffolding

Now if you run Get-Scaffolder, you’ll see there are two new ones:

image

If you want, you can invoke these directly (e.g., Scaffold LinqToSqlScaffolding.Repository <modelType>). They take roughly the same parameters as the standard EF repository and DbContext scaffolders.

But if you want to use LINQ to SQL by default, just update your default settings:

Set-DefaultScaffolder Repository LinqToSqlScaffolding.Repository

Now, whenever you call “Scaffold Repository” or even “Scaffold Controller”, it will generate code that works with LINQ to SQL. Note that to get this actually talking to a database successfully, you’ll need to:

  • Annotate your model classes with LINQ to SQL mapping attributes as described here, or provide a LINQ to SQL mapping file
  • Add a connection string called AppDb to your Web.config file, and ensure there’s really a database listening for connections, and set up the database schema to match your model.

Also, whenever you generate a controller for this, be sure to pass the –Repository switch because otherwise the controller will contain inline Entity Framework code.

Note that LINQ to SQL scaffolding support is basic, to say the least, and is primarily here to demonstrate how you can create a custom scaffolding package. In due course I hope others will create scaffolding packages to support other data access technologies, such as NHibernate. If you want the fame and glory and decide to be the one who builds that package for the community, let me know!

What’s next?

There’s still plenty more to cover about scaffolding. In the next post, I’ll describe how you can customise the T4 templates that define scaffolders’ output, and how you can create entirely new scaffolders of your own.

42 Responses to MvcScaffolding: Standard Usage

  1. John Teague

    Are these open source? Where is the code?

  2. John Teague

    Ahh, I’m going to assume this is it:
    http://mvcscaffolding.codeplex.com/

  3. John Teague

    Ahh, I’m going to assume this is it:
    http://mvcscaffolding.codeplex.com/

  4. The term ‘Get-Scaffolder’ is not recognized as the name of a cmdlet
    Is there an update to Nuget that I need?

  5. Steve

    Tony – First, sorry if it wasn’t clear from this post, but you need to install the MvcScaffolding package as described in the previous post (http://blog.stevensanderson.com/2011/01/13/scaffold-your-aspnet-mvc-3-project-with-the-mvcscaffolding-package/). Second, make sure you’re using the 1.0 version of NuGet – the one that comes with ASP.NET MVC 3. If you’re already doing that and still having trouble please email me so I can follow up with you.

  6. Simon

    Hi, I have the same problem as Tony.
    Maybe because I installed Asp.net mvc3 RTM?

  7. Hi Steve,

    How can I configure which database to use? And where is the data saved by default?

    I have installed SQL Server CE 4.0. I added a database called “SimpleTest.sdf” to the App_Data folder and then added a connectionstring to my Web.config with the same name as the DbContext that was scaffolded:

    When I run the application, I everything works, but my database isn’t used. That means it’s storing the data somewhere else and I don’t know where or how to change this.

    I guess I’m just overlooking something very simple here :-)

  8. Oops, my connectionstring didn’t make it through.

    I added this connectionstring: <add name=”SimpleTestContext” connectionString=”Data Source=|DataDirectory|SimpleTest.sdf” providerName=”System.Data.SqlServerCe.4.0″ />

  9. Steve – Scaffolding works now. I was missing
    Install-Package MvcScaffolding

  10. Hi Steven, great job in MVCScaffolding.
    Please tell me where are the informations that are used by the DbContext by default. I know it uses the SqlExpress, but it connects with wich credentials?
    I didn’t find any config in the web.config files, neither can see anything in the .NET Reflector.

    Thank you,
    Vinicius Quaiato.

  11. Steve Gentile

    Great stuff Steve! I’m looking forward to hearing more about customizing the T4 templates (ie. I’d like to use the Telerik MVC Grid for the Index vs the tables)

    Thanks! – this is something I’ve been waiting for in MVC for awhile – so this rocks! :)

  12. Ok, apparently MvcScaffolding uses SqlExpress (didn’t even know I had it installed :) ). So how can I change this?

  13. Great stuff glad to see you at Microsoft I have your Pro ASP.NET MVC 1 book good gob of writing I’m looking forward to learning more from your writings and knowledge
    Thank you and thank you Microsoft

  14. Epic stuff mate

    Where can I find the T4 templates for editing?

    Any plans on generating Unit Test Fixtures too?

  15. I think making the repository class partial would make it easier to play along the generated class in a different file for validations and other methods.

  16. PabloBlamirez

    Hi, currently a dbcontext is created by each repository. Has it been discussed about separating out the unit of work from the repository and moving the save method to the uow (in the default template). I realise that it is down to taste and if I want to change it I can easily do so with t4.
    I understand if at this stage you’d prefer feedback about the scaffolding mechanism rather than the actual code that is generated.

    Paul

  17. Jay

    After installing and setting LinqToSql Scaffolding package as default and running the scaffold command, it is searching for InsertOrUpdate method in the repository and fails build. Probably update on template is required for Controller when LinqToSql is used.

  18. Alex

    Hi Steve,

    Thank you for your great books. I’m looking forward to buying the 3rd edition of Pro ASP.NET MVC.

    But I have a question. I see that you are using Entity Framework more and more often. Will you make a switch to it in the 3rd book or will you still be using Linq To Sql?

  19. trace-projects

    Good day Steve,

    am trying to do then using Visual Web Developer express instead of Visual Studio 2010. so far I can install, but I can’t get it to work. the actions/commands could not be seen by Powershell. is this a VWD Express limitation, or is there something I must do first before expecting this to work on VWD EXpress?

    Thanks

  20. xiecsuk

    I have a website project that contains 3 subprojects. The main subproject is the code for the website. I then have a subproject for unit testing and a 3rd subproject for the data domain in which I have created a Models folder and a C# Match class. When I issue the Scaffold Controller Match command I get the following error message

    Invoke-Scaffolder : Cannot find a model type corresponding to a controller called ‘Match’. Try supplying a -ModelType parameter value.
    At line:1 char:9
    + Scaffold <<<< Controller Match
    + CategoryInfo : NotSpecified: (:) [Invoke-Scaffolder], RuntimeException
    + FullyQualifiedErrorId : T4Scaffolding.Cmdlets.InvokeScaffolderCmdlet

    Will Scaffolding work with subprojects?

  21. Marko

    I have the same question/problem as xiecsuk

  22. Pingback: @stevesanderson: MvcScaffolding « Random misspellings

  23. Robo

    Great article!

    Was wondering if you know how to pass a custom object to a template.cs.t4 using Invoke-Scaffolder? I call a custom .net assembly that returns an array of ColumnItems[] and can’t seem to get the custom array of objects to the t4 template.

    Any help is much appreciated!

  24. Pingback: Scaffolding Actions and Unit Tests with MvcScaffolding « Steve Sanderson’s blog

  25. Pingback: MvcScaffolding: Overriding the T4 Templates « Steve Sanderson’s blog

  26. Tommy Bergeron

    Hi!

    First, MVCScaffolding is AWESOME and it’s very fun to use, good job guys!

    But I have a question. I created a new database so now I don’t have any of my tables in it yet. Is there any way of recreating my tables with a simple command? I tried hard to find a way but found nothing yet.

    Anyone has an idea? I still have all my models, etc. I just want to recreate the tables so I could continue to use them.

    Thanks a lot!

  27. Yay for -NoChildItems. Came in handy when I was trying to customize my controller scaffolder and I didn’t want it to regenerate all the views every time.

  28. Marko

    When using database first approach in EF how can you get the Scaffolding to recognize foreign keys? When i add a controller the “Normal” way, right click add controller, the controllers edit and create methods adds the select options to ViewBag of foreign key options, but when i issue the command “Scaffold Controller” they are missing.

  29. Steve F

    A great tool thanks Steve! FYI there is a typo in the “Using the built-in Scaffolders” section where you say the parameter name is “-TemplateName”. Looks like it is just simply “-Template”.

    Thanks again.

  30. Adam Tolley

    Steve F: Thanks! I was having a problem with ‘TemplateName’, switching to ‘Template’ fixed it.

    Steve S: This stuff is really great, thanks for the good work.

  31. Following this excellent post but using VB rather C# I think I found a typo. The generated Context produces sample code which enables a destruction of the database and is given as …

    ‘System.Data.Entity.Database.SetInitializer(New System.Data.Entity.DropCreateDatabaseIfModelChanges(Of .Models.Context)())

    However, I found this produced compilation errors so my version is …
    System.Data.Entity.Database.DbDatabase.SetInitializer(New System.Data.Entity.Database.DropCreateDatabaseIfModelChanges(Of .Models.Context)())

  32. Steve

    Steve F – thanks for letting me know. Fixed.

  33. Linda Gravell

    Steve, I have built my web page using MvcScaffolding. Now, I would like to change my database from SQLEXPRESS to SQL SERVER. So I modified my connection string, but that did not change to my production database. Please indicate how I can change to my SQL database. thanks, Linda

  34. David Johnson

    System.__ComObject context = new System.__ComObject();

    give an error
    Error 1 ‘System.__ComObject’ is inaccessible due to its protection level

    everything worked great until I added the linqtosql

  35. It?s really a great and useful piece of info. I?m glad that you simply shared this useful information with us. Please stay us up to date like this. Thank you for sharing.

  36. What i don’t understood is actually how you are not actually much more smartly-liked than you might be right now. You are so intelligent. You recognize therefore considerably when it comes to this matter, produced me in my opinion imagine it from numerous varied angles. Its like women and men are not fascinated until it?s something to do with Lady gaga! Your personal stuffs outstanding. At all times handle it up!

  37. of course like your web site but you need to take a look at the spelling on several of your posts. Many of them are rife with spelling problems and I to find it very bothersome to inform the truth however I?ll surely come back again.

  38. Sam

    Hi Steve,

    Wonder how can I change the location of the database? Right now it use the default SQLExpress, but I want to store the data in a remote server with SQL Authentication and as a specific database name without using the NameSpace.ContextClassName pattern.

    Some thing like

    Thanks

    Sam.

  39. Sam

    Data Source=remoteServer,7788;Initial Catalog=databaseName;User ID=user;Password=password

  40. Sam

    I figured it out :D

  41. Andre

    Has the -Folder option been removed in MvcScaffolding 1.0.6? I get “A parameter cannot be found that matches parameter name ‘Folder’” when trying to scaffold a repository.

  42. Andre

    I added the feature in the T4Scaffolder, as that is where it was missing (from context and repo scaffolding). I like to put my repos in a seperate lib, but I don’t need the repo files iin a subfolder.