Continuing on from Part #3 of the Ground Up Series. Today we'll be looking at quickly scaffolding up a basic CRUD interface.
The source code is available here.
Scaffolding with Commands
Visual Studio currently (in version 2013) offers a GUI to quickly build out a controller, the required action methods and a bunch of views to handle the UI. As with all things in ASP.NET 5, in order to split off from Visual Studio (and run on other platforms) - command line is now the default. Visual Studio will still offer a GUI to handle these actions but it will simply call down into the command line interface.
Let's look at adding in Code Generation and Scaffolding out a Controller and Views. We'll need a package to do handle the Code Generation for us.
kpm install Microsoft.Framework.CodeGenerators.Mvc 1.0.0-beta2
As before, this will bring down the package and update our project.json
with the dependency details.
We now need to expose this as a k command
in our project.json
. Add the following to the commands section:
"gen": "Microsoft.Framework.CodeGeneration"
We can now execute the CodeGeneration by using:
k gen
This will spit back that we have two Code Generators installed. Controller
and View
. You can run k gen controller -?
to get help on on the controller
generator as an example. This hook is extensible, you can imagine other generators becoming available as the ecosystem is flushed out.
Here's a full example of scaffolding out a controller for full CRUD with an associated DBContext and Model to modify.
k gen controller -name TodoController --dataContext GroundUpDbContext --model TodoItem
This will generate a TodoController
controller class with all the appropriate CRUD action results, database access and views for:
- Create
- Delete
- Details
- Edit
- Index
You can take these generated files and build on them to flesh out your solution.
There are a lot more options available as part of these generators that you can use to customise the output. You can (for instance) opt in to async
controllers, and the appropriate controller code will be generated, including async database access.
These flags only get you so far however. And if you try and run the project you'll get a compile error:
TodoController.cs(79,34): error CS1061: 'ChangeTracker' does not contain a definition for 'Entry' and no extension method 'Entry' accepting a first argument of type 'ChangeTracker' could be found
There is a mismatch between the code generated, and what is going to work with our current beta bits. Whilst this issue is likely to be fixed shortly, there are a lot of benefits in being able to customise the templates.
Edit: Read a comment from Mirko Geffken which addresses this.
Customising the code that is generated
Generating code can be a nice way to get a quick prototype up and running, but it's unlikely that these generated files are going to be exactly to your liking. The base templates are all part of the NuGet Package. Browse to:
%userprofile%\.kpm\packages\Microsoft.Framework.CodeGenerators.Mvc\1.0.0-beta2\
And then copy the Templates
directory into the root of your project. If you've used the scaffolding functionality in previous versions of MVC, then the big difference here is T4
is gone - these files are all Razor
based, which I find to be much more intuitive.
The offending peice of code is in /Templates/ControllerGenerator/ControllerWithContext.cshtml
line 224
:
db.ChangeTracker.Entry(@Model.ModelVariable).State = EntityState.Modified;
For now, we'll simply comment (//
) out the offending code. This shortcut will mean that we won't have edit support for now, but it should still demonstrate how the scaffolding system works.
Let's make one further change in /Templates/ViewGenerator/Create.cshtml
on line 66
:
// If the property is a primary key and Guid, then the Guid is generated in the controller. Hence, this propery is not displayed on the view.
if (property.IsPrimaryKey && IsPropertyGuid(property))
{
continue;
}
We'll rip out this IsPropertyGuid
method (as ours as an integer), it now becomes:
if (property.IsPrimaryKey)
{
continue;
}
If you re-run the generator command it will not succeed as your project doesn't currently compile. Just delete the previously created TodoController.cs
and then a subsequent run will succeed.
Kick the app into gear again with k web
, and then browse to http://localhost:5000/todo
You can now Create, Not Edit (for now), and Delete Todo Items in the system.