{"id":54658,"date":"2024-11-20T08:00:00","date_gmt":"2024-11-20T16:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=54658"},"modified":"2024-12-06T09:25:23","modified_gmt":"2024-12-06T17:25:23","slug":"introducing-dotnet-scaffold","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/introducing-dotnet-scaffold\/","title":{"rendered":"dotnet scaffold &#8211; Next Generation Content Creation for .NET"},"content":{"rendered":"<p>Scaffolding in Visual Studio for ASP.NET Core projects has been a long-standing\nfeature which was added shortly after ASP.NET Core was\nreleased. We have also had support for scaffolding from the command line\nfor many years. From that command line experience, we have heard\nfeedback from many users that we need an interactive CLI experience for\nscaffolding. To that goal, we have been working on a new <strong>interactive<\/strong>\nCLI tool, <code>dotnet scaffold<\/code>. This CLI tool has now been released as a\npreview. In this post we will describe how you can acquire and use this\nnew command line tool. This tool is open source, you can view the code\nin the <a href=\"https:\/\/github.com\/dotnet\/Scaffolding\">scaffolding repo<\/a>. That\nrepository contains the code for the <code>dotnet scaffold<\/code> tool as well as\nother scaffolding related code.<\/p>\n<h2>Installing <code>dotnet scaffold<\/code><\/h2>\n<p>To install this tool we will use the dotnet tool command. Execute the\ncommand below to get the latest released version installed.<\/p>\n<p><code>dotnet tool install --global Microsoft.dotnet-scaffold<\/code><\/p>\n<p>To install a specific version, visit the <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.dotnet-scaffold\">package on\nnuget.org<\/a>.\nTo install a specific version, visit the <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.dotnet-scaffold\">package on\nnuget.org<\/a>.\nFor more info on how to manage dotnet tools see the docs at <a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/tools\/global-tools\">.NET\ntools &#8211; .NET CLI | Microsoft\nLearn<\/a>.\nIn the command above we are installing the tool globally, but you can\nalso install tools local to a folder. The .NET tools docs have more info\non both of those approaches <a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/tools\/global-tools\">.NET tools &#8211; .NET CLI | Microsoft Learn<\/a>.<\/p>\n<h2>Using <code>dotnet scaffold<\/code><\/h2>\n<p>By default, <code>dotnet scaffold<\/code> is an interactive tool, meaning that you\ninvoke it, and it will prompt you for info as needed. For automation,\nyou can pass in all the parameter values, but we will discuss that in a\nfuture post. Before running <code>dotnet scaffold<\/code>, make sure to change\ndirectories (cd) to a folder where a .NET Core project exists. dotnet\nscaffold has support for the following ASP.NET Core project types.<\/p>\n<ul>\n<li>Web app<\/li>\n<li>Web API<\/li>\n<li>.NET Aspire<\/li>\n<li>Blazor<\/li>\n<\/ul>\n<p>In this post we will focus on the Web app option to show you around\n<code>dotnet scaffold<\/code>, but all the scaffolders follow the same patterns and\nprompts.<\/p>\n<p>I created a new ASP.NET Core 9 web app using dotnet new with the command\ndotnet new webapp -o MyWebApp. Then I used <strong>cd<\/strong> to change into that\ndirectory. When you run <code>dotnet scaffold<\/code>, you\u2019ll be prompted to select\nthe scaffolding category. See the screenshot below.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/01-scaffolding-select-step.png\" alt=\"select step\" \/><\/p>\n<p>In the image above <code>dotnet scaffold<\/code> shows a list of the scaffolding\ncategories that are currently supported. To navigate this menu, you will\nuse the up and down arrow keys on your keyboard to select the desired\ncategory. In the future as we add more scaffolders more categories may\nappear. Here you\u2019ll select the category of what you are wanting to\ngenerate into your project. For example, let\u2019s explore the Razor Pages\noption. To select a category, navigate to it and type Return. That will\ntake you into the selected option. If you select an incorrect option,\nyou can always use Back under Navigation to go back to the previous\nselection. After entering the Razor Pages option, you will see the\nfollowing options.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/02-scaffolding-select-command.png\" alt=\"select command\" \/><\/p>\n<p>Now <code>dotnet scaffold<\/code> is prompting for the specific scaffolder which\nshould be invoked. In this case we see two options, the first option is\nto create a new empty Razor Page. The second option will generate Razor\nPages based on a model class that is a part of the project. Values will\nbe persisted using Entity Framework into the selected database provider.\nLet\u2019s first run through the Empty scaffolder and then the CRUD one. The\nempty scaffolder will generate a new Razor page with an associated code\nfile. This is equivalent to running dotnet new page. The generated files\nwill not have any customizations.<\/p>\n<p>When you have the option <strong>Razor Page &#8211; Empty<\/strong>, selected hit the Return\nkey to go into that option. After that you\u2019ll be prompted to select the\ntarget project.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/03-scaffolding-select-project.png\" alt=\"select project\" \/><\/p>\n<p>In this case we only have one, so we will select MyWebApp and hit the\nReturn key. Then it will prompt for the name of the Razor Page to\ncreate. Give it the name About and hit the Return key. You\u2019ll see the\ncommand working and then you should see the result below.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/04-scaffolding-specify-filename.png\" alt=\"specify file name\" \/><\/p>\n<p>After this has completed you should see the files About.cshtml and\nAbout.cshtml.cs in the current working directory. When running this\nscaffold, it will use the current directory as the output location. Now\nlet\u2019s move on to see how the Razor Page EF option behaves.<\/p>\n<p>Before invoking the EF scaffolders you need a model class for it to\nscaffold content for. I\u2019ve created a new web app with the same command\nas before, dotnet new webapp -o MyWebApp and I\u2019ve added the following\nclass in the root of the project.<\/p>\n<pre><code class=\"language-cs\">namespace MyWebApp;\r\n\r\npublic class Contact\r\n{\r\n    public int Id { get; set; }\r\n\r\n    public string? Firstname { get; set; }\r\n\r\n    public string? Lastname { get; set; }\r\n\r\n    public string? Email { get; set; }\r\n}<\/code><\/pre>\n<p>This is a very basic model class that can be used with Entity Framework.\nNow we are ready to invoke <code>dotnet scaffold<\/code>. After starting it, select\nthe Razor Pages category and then the <strong>Razor Pages with Entity\nFramework (CRUD)<\/strong> option. It will prompt you to select the project,\nsince there is only one project in this case you can hit Return because\nit\u2019s already selected. Next <code>dotnet scaffold<\/code> will prompt you to select\nthe model class as shown below.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/05-scaffolding-select-model-class.png\" alt=\"select model class\" \/><\/p>\n<p>Select Contact and hit the Return key to proceed. The next screen will\nprompt you for the name of the database context. For this example, give\nit the name ContactDbContext and hit the Return key. It\u2019s recommended\nfor this value to end with DbContext based on convention, but that is\nnot required. See the following image.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/06-scaffolding-dbcontext-class-name.png\" alt=\"select DB provider\" \/><\/p>\n<p>After you hit the Return key, you will be prompted to select the\ndatabase provider.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/07-scaffolding-provider.png\"><img decoding=\"async\" class=\"size-full wp-image-54815 alignnone\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/07-scaffolding-provider.png\" alt=\"shows scaffolding db providers\" width=\"624\" height=\"245\" srcset=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/07-scaffolding-provider.png 624w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/07-scaffolding-provider-300x118.png 300w\" sizes=\"(max-width: 624px) 100vw, 624px\" \/><\/a><\/p>\n<p>The following list summarizes the options on that screen.<\/p>\n<ul>\n<li>npgsql-efcore = PostgreSQL<\/li>\n<li>sqlserver-efcore = SQL Server<\/li>\n<li>sqlite-efcore = SQLite<\/li>\n<li>cosmos-efcore = Cosmos DB<\/li>\n<\/ul>\n<p>To keep things simple, we will select the sqlite-efcore option. SQLite\nis a file based database and doesn\u2019t have any external dependencies.\nSelect that option and hit Return. You\u2019ll be prompted to select what\noperations should be scaffolded. See the next image.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/08-scaffolding-page-type.png\" alt=\"select page type\" \/><\/p>\n<p>You can select an individual item to be created, or you can select the\nCRUD option to scaffold the full set of pages. Select the CRUD option.\nNext, you\u2019ll be prompted if you want to include prerelease packages.\nSince we are working with .NET 9 preview, select Yes for that option and\nhit Return. After that the scaffolding operation will start. You\u2019ll see\na spinner showing that it is running, and it will emit messages for the\noperations that are taking place. When it is complete you should see a\nresult similar to the following screenshot.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/09-scaffolding-crud-finished.png\" alt=\"output from scaffolding crud\" \/><\/p>\n<p>After performing this operation, the following changes will have been\napplied to the project.<\/p>\n<ul>\n<li>The project file has package references added for Entity Framework<\/li>\n<li>Program.cs has been updated to initialize the database connection<\/li>\n<li>appsettings.json has been updated with connection information<\/li>\n<li>ContactDbContext.cs has been created and added to the project root\ndirectory<\/li>\n<li>Razor Pages for CRUD operations has been added to the Pages folder<\/li>\n<\/ul>\n<p>The content has been generated but the database has not yet been\ninitialized. To prep the database, we need to create a migration and\nthen update the database. Do that with the following commands.<\/p>\n<ul>\n<li>dotnet ef migrations add initialMigration\n<ul>\n<li>This will add a new migration named initialMigration. You can give\nit whatever name you prefer here.<\/li>\n<\/ul>\n<\/li>\n<li>dotnet ef database update\n<ul>\n<li>This will apply the migrations to the database<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>After running those commands, you should be ready to run the app with\nthe <strong>dotnet run<\/strong> command. After the app starts the URL will be shown\nin the terminal, open that URL in your browser with \/ContactPages at the\nend of the URL. You should see something like the following.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/10-scaffolding-browser-contact.png\" alt=\"contact page shown in browser\" \/><\/p>\n<p>Using this page you can create new contacts and manage existing ones as\nwell. After you add some contacts they will appear on this page as shown\nbelow.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/11\/11-scaffolding-contact-page-with-contacts.png\" alt=\"contact page with contacts shown in browser\" \/><\/p>\n<p>Now you have an ASP.NET Core Razor Pages web app which can manage a\ncontact list. After scaffolding you will likely want to customize the\ngenerated content to suit your needs. You can use <code>dotnet scaffold<\/code> to\nscaffold other content as you develop your app.<\/p>\n<h2>Recap<\/h2>\n<p>In this post we have used <code>dotnet scaffold<\/code> to add Razor Pages to a new\nASP.NET Core .NET 9 web app. Keep an eye on this blog for more\ninformation on changes to <code>dotnet scaffold<\/code>. We are hoping that you will\ntry out this new command line tool and provide us some feedback so that\nwe can improve this going forward. In particular, we are very interested in\nfeedback on the interactivity of this command line tool.\nThe following section has info on how you can provide feedback.<\/p>\n<h2>Feedback<\/h2>\n<p>You can share feedback with us by filing an issue in the <a href=\"https:\/\/github.com\/dotnet\/Scaffolding\">Scaffolding\nrepo<\/a>. You can also send feedback\nvia the <a href=\"https:\/\/developercommunity.visualstudio.com\/home\">Developer\nCommunity<\/a>: report any\nbugs or issues via <a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/how-to-report-a-problem-with-visual-studio\">report a\nproblem<\/a>\nand share your <a href=\"https:\/\/developercommunity.visualstudio.com\/report?space=8&amp;entry=suggestion\">suggestions for new\nfeatures<\/a>\nor improvements to existing ones. Let us know what you think in the comment below.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introducing a new command line tool dotnet scaffold, a new interactive way to create projects in .NET.<\/p>\n","protected":false},"author":357,"featured_media":54659,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,7509,7783,7251,756,646,7593],"tags":[7797],"class_list":["post-54658","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-aspnetcore","category-aspire","category-blazor","category-csharp","category-visual-studio","category-visual-studio-code","tag-dotnet-9"],"acf":[],"blog_post_summary":"<p>Introducing a new command line tool dotnet scaffold, a new interactive way to create projects in .NET.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/54658","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/357"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=54658"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/54658\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/54659"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=54658"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=54658"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=54658"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}