diff --git a/docs/_authors/steve-smith.rst b/docs/_authors/steve-smith.rst index 6e017f157e4f..dafb309165fe 100644 --- a/docs/_authors/steve-smith.rst +++ b/docs/_authors/steve-smith.rst @@ -1,4 +1,4 @@ -:orphan: +.. :orphan: .. _Author: diff --git a/docs/index.rst b/docs/index.rst index e2aa83bca4e6..a89768db8788 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -22,6 +22,7 @@ ASP.NET MVC 6 :maxdepth: 1 migrating/migratingfrommvc5/migratingfrommvc5 + migrating/migratingconfig/migratingconfig Web API ------- diff --git a/docs/migrating/migratingauthmembership/_static/AddLoginPartial.png b/docs/migrating/migratingauthmembership/_static/AddLoginPartial.png new file mode 100644 index 000000000000..aa75f5a8232a Binary files /dev/null and b/docs/migrating/migratingauthmembership/_static/AddLoginPartial.png differ diff --git a/docs/migrating/migratingauthmembership/migratingauthmembership.rst b/docs/migrating/migratingauthmembership/migratingauthmembership.rst new file mode 100644 index 000000000000..8b902bd5a8a6 --- /dev/null +++ b/docs/migrating/migratingauthmembership/migratingauthmembership.rst @@ -0,0 +1,163 @@ +Migrating Authentication and Identity From ASP.NET MVC 5 to MVC 6 +================================================================= +By `Steve Smith`_ | Originally Published: 1 June 2015 + +.. _`Steve Smith`: Author_ + +In the previous article we `migrated configuration from an ASP.NET MVC 5 project to MVC 6 `_. In this article, we migrate the registration, login, and user management features. + +This article covers the following topics: + - Configure Identity and Membership + - Migrate Registration and Login Logic + - Migrate User Management Features + +You can download the finished source from the project created in this article HERE **(TODO)**. + +Configure Identity and Membership +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In ASP.NET MVC 5, authentication and identity features are configured in Startup.Auth.cs and IdentityConfig.cs, located in the App_Start folder. In MVC 6, these features are configured in Startup.cs. Before pulling in the required services and configuring them, we should add the required dependencies to the project. Open project.json and add "Microsoft.AspNet.Identity.EntityFramework" and "Microsoft.AspNet.Identity.Cookies" to the list of dependencies: + +.. code-block:: javascript + + "dependencies": { + "Microsoft.AspNet.Server.IIS": "1.0.0-beta3", + "Microsoft.AspNet.Mvc": "6.0.0-beta3", + "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta3", + "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-beta3", + "Microsoft.AspNet.Security.Cookies": "1.0.0-beta3" + }, + +Now, open Startup.cs and update the ConfigureServices() method to use Entity Framework and Identity services: + +.. code-block:: c# + + public void ConfigureServices(IServiceCollection services) + { + // Add EF services to the services container. + services.AddEntityFramework(Configuration) + .AddSqlServer() + .AddDbContext(); + + // Add Identity services to the services container. + services.AddIdentity(Configuration) + .AddEntityFrameworkStores(); + + services.AddMvc(); + } + +At this point, there are two types referenced in the above code that we haven't yet migrated from the MVC 5 project: ApplicationDbContext and ApplicationUser. Create a new Models folder in the MVC 6 project, and add two classes to it corresponding to these types. You will find the MVC 5 versions of these classes in /Models/IdentityModels.cs, but we will use one file per class in the migrated project since that's more clear. + +ApplicationUser.cs: + +.. code-block:: c# + + using Microsoft.AspNet.Identity; + + namespace NewMvc6Project.Models + { + public class ApplicationUser : IdentityUser + { + } + } + +ApplicationDbContext.cs: + +.. code-block:: c# + + using Microsoft.AspNet.Identity.EntityFramework; + using Microsoft.Data.Entity; + + namespace NewMvc6Project.Models + { + public class ApplicationDbContext : IdentityDbContext + { + private static bool _created = false; + public ApplicationDbContext() + { + // Create the database and schema if it doesn't exist + // This is a temporary workaround to create database until Entity Framework database migrations + // are supported in ASP.NET 5 + if (!_created) + { + Database.AsMigrationsEnabled().ApplyMigrations(); + _created = true; + } + } + + protected override void OnConfiguring(DbContextOptions options) + { + options.UseSqlServer(); + } + } + } + +The MVC 5 Starter Web project doesn't include much customization of users, or the ApplicationDbContext. When migrating a real application, you will also need to migrate all of the custom properties and methods of your application's user and DbContext classes, as well as any other Model classes your application utilizes (for example, if your DbContext has a DbSet, you will of course need to migrate the Album class). + +With these files in place, the Startup.cs file can be made to compile by updating its using statements: + +.. code-block:: c# + + using Microsoft.Framework.ConfigurationModel; + using Microsoft.AspNet.Hosting; + using NewMvc6Project.Models; + using Microsoft.AspNet.Identity; + +Our application is now ready to support authentication and identity services - it just needs to have these features exposed to users. + +Migrate Registration and Login Logic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +With identity services configured for the application and data access configured using Entity Framework and SQL Server, we are now ready to add support for registration and login to the application. Recall that `earlier in the migration process `_ we commented out a reference to _LoginPartial in _Layout.cshtml. Now it's time to return to that code, uncomment it, and add in the necessary controllers and views to support login functionality. + +Update _Layout.cshtml; uncomment the @Html.Partial line: + +.. code-block:: c# + +
  • @Html.ActionLink("Contact", "Contact", "Home")
  • + + @*@Html.Partial("_LoginPartial")*@ + + + +Now, add a new MVC View Page called _LoginPartial to the Views/Shared folder: + +.. image /static/AddLoginPartial.png + +Update _LoginPartial.cshtml with the following code (replace all of its contents): + +.. code-block:: c# + +@using System.Security.Principal + +@if (User.Identity.IsAuthenticated) +{ + using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" })) + { + @Html.AntiForgeryToken() + + } +} +else +{ + +} + +At this point, you should be able to refresh the site in your browser. + + + +Summary +^^^^^^^ + +ASP.NET 5 and MVC 6 introduce changes to the ASP.NET Identity 2 features that shipped with ASP.NET MVC 5. In this article, you have seen how to migrate the authentication and user management features of an ASP.NET MVC 5 project to MVC 6. + +.. include:: /_authors/steve-smith.rst diff --git a/docs/migrating/migratingconfig/_static/add-config-json.png b/docs/migrating/migratingconfig/_static/add-config-json.png new file mode 100644 index 000000000000..7b7f3aaec465 Binary files /dev/null and b/docs/migrating/migratingconfig/_static/add-config-json.png differ diff --git a/docs/migrating/migratingconfig/migratingconfig.rst b/docs/migrating/migratingconfig/migratingconfig.rst new file mode 100644 index 000000000000..7948f1c117ea --- /dev/null +++ b/docs/migrating/migratingconfig/migratingconfig.rst @@ -0,0 +1,84 @@ +Migrating Configuration From ASP.NET MVC 5 to MVC 6 +=================================================== +By `Steve Smith`_ | Originally Published: 1 June 2015 + +.. _`Steve Smith`: Author_ + +In the previous article we began `migrating an ASP.NET MVC 5 project to MVC 6 `_. In this article, we migrate the configuration feature from ASP.NET MVC 5 to ASP.NET MVC 6. + +This article covers the following topics: + - Set up Configuration + - Migrate Configuration Settings from web.config + +You can download the finished source from the project created in this article HERE **(TODO)**. + +Set up Configuration +^^^^^^^^^^^^^^^^^^^^ + +ASP.NET 5 and ASP.NET MVC 6 no longer use the Global.asax and Web.config files that previous versions of ASP.NET utilized. In earlier versions of ASP.NET, application startup logic was placed in an Application_StartUp() method within Global.asax. Later, in ASP.NET MVC 5, a Startup.cs file was included in the root of the project, and was called using an OwinStartupAttribute when the application started. ASP.NET 5 (and ASP.NET MVC 6) have adopted this approach completely, placing all startup logic in the Startup.cs file. + +The web.config file has also been replaced in ASP.NET 5. Configuration itself can now be configured, as part of the application startup procedure described in Startup.cs. Configuration can still utilize XML files, if desired, but typically ASP.NET 5 projects will place configuration values in a JSON-formatted file, such as config.json. ASP.NET 5's configuration system can also easily access environment variables, which can provide a more secure and robust location for environment-specific values. This is especially true for secrets like connection strings and API keys that should not be checked into source control. + +For this article, we are starting with the partially-migrated ASP.NET MVC 6 project from `the previous article `_. To configure Configuration using the default MVC 6 settings, add the following constructor to the Startup.cs class in the root of the project: + +.. code-block:: c# + + public IConfiguration Configuration { get; set; } + + public Startup(IHostingEnvironment env) + { + // Setup configuration sources. + Configuration = new Configuration() + .AddJsonFile("config.json") + .AddEnvironmentVariables(); + } + +Note that at this point the Startup.cs file will not compile, as we still need to add some using statements and pull in some dependencies. Add the following two using statements: + +.. code-block:: c# + + using Microsoft.Framework.ConfigurationModel; + using Microsoft.AspNet.Hosting; + +Next, open project.json and add the Microsoft.Framework.ConfigurationModel.Json dependency: + +.. code-block:: javascript + + { + "webroot": "wwwroot", + "version": "1.0.0-*", + "dependencies": { + "Microsoft.AspNet.Server.IIS": "1.0.0-beta3", + "Microsoft.AspNet.Mvc": "6.0.0-beta3", + "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta3" + }, + ... + } + +Finally, add a config.json file to the root of the project. + +.. image:: _static/add-config-json.png + +Migrate Configuration Settings from Web.config +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Our ASP.NET MVC 5 project included the required database connection string in Web.config, in the element. In our MVC 6 project, we are going to store this information in the config.json file. Open Config.json, and you should see that it already includes the following: + +.. code-block:: javascript + + { + "Data": { + "DefaultConnection": { + "ConnectionString": "Server=(localdb)\\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;" + } + } + } + +Change the name of the Database from _CHANGE_ME. In the case of this migration, we are going to point to a new database, which we'll name NewMvc6Project to match our migrated project name. + +Summary +^^^^^^^ + +ASP.NET 5 places all Startup logic for the application in a single file in which necessary services and dependencies can be defined and configured. It replaces the web.config file with a flexible configuration feature that can leverage a variety of file formats, such as JSON, as well as environment variables. + +.. include:: /_authors/steve-smith.rst diff --git a/docs/migrating/migratingfrommvc5/_static/Mvc5Project.zip b/docs/migrating/migratingfrommvc5/_static/Mvc5Project.zip new file mode 100644 index 000000000000..5211576c5792 Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/Mvc5Project.zip differ diff --git a/docs/migrating/migratingfrommvc5/_static/bundle-screenshot.png b/docs/migrating/migratingfrommvc5/_static/bundle-screenshot.png new file mode 100644 index 000000000000..9b0c17410739 Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/bundle-screenshot.png differ diff --git a/docs/migrating/migratingfrommvc5/_static/contact-page.png b/docs/migrating/migratingfrommvc5/_static/contact-page.png new file mode 100644 index 000000000000..7bc131e81805 Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/contact-page.png differ diff --git a/docs/migrating/migratingfrommvc5/_static/hello-world.png b/docs/migrating/migratingfrommvc5/_static/hello-world.png new file mode 100644 index 000000000000..f7471bad597d Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/hello-world.png differ diff --git a/docs/migrating/migratingfrommvc5/_static/layout-cshtml.png b/docs/migrating/migratingfrommvc5/_static/layout-cshtml.png new file mode 100644 index 000000000000..15ad3815c212 Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/layout-cshtml.png differ diff --git a/docs/migrating/migratingfrommvc5/_static/new-project-mvc6.png b/docs/migrating/migratingfrommvc5/_static/new-project-mvc6.png new file mode 100644 index 000000000000..bf8b0f430496 Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/new-project-mvc6.png differ diff --git a/docs/migrating/migratingfrommvc5/_static/new-project-select-empty-aspnet5-template.png b/docs/migrating/migratingfrommvc5/_static/new-project-select-empty-aspnet5-template.png new file mode 100644 index 000000000000..84720311954d Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/new-project-select-empty-aspnet5-template.png differ diff --git a/docs/migrating/migratingfrommvc5/_static/new-project-select-mvc-template.png b/docs/migrating/migratingfrommvc5/_static/new-project-select-mvc-template.png new file mode 100644 index 000000000000..0c049b3dddb1 Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/new-project-select-mvc-template.png differ diff --git a/docs/migrating/migratingfrommvc5/_static/new-project.png b/docs/migrating/migratingfrommvc5/_static/new-project.png new file mode 100644 index 000000000000..64275ec92ea6 Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/new-project.png differ diff --git a/docs/migrating/migratingfrommvc5/_static/project-structure-bower.png b/docs/migrating/migratingfrommvc5/_static/project-structure-bower.png new file mode 100644 index 000000000000..edde80ca80d5 Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/project-structure-bower.png differ diff --git a/docs/migrating/migratingfrommvc5/_static/project-structure-controller-view.png b/docs/migrating/migratingfrommvc5/_static/project-structure-controller-view.png new file mode 100644 index 000000000000..78f2d7552aaf Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/project-structure-controller-view.png differ diff --git a/docs/migrating/migratingfrommvc5/_static/task-runner-explorer.png b/docs/migrating/migratingfrommvc5/_static/task-runner-explorer.png new file mode 100644 index 000000000000..7aa4699fc466 Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/task-runner-explorer.png differ diff --git a/docs/migrating/migratingfrommvc5/_static/updated-gruntfile-with-concat.png b/docs/migrating/migratingfrommvc5/_static/updated-gruntfile-with-concat.png new file mode 100644 index 000000000000..98c518ba2e76 Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/updated-gruntfile-with-concat.png differ diff --git a/docs/migrating/migratingfrommvc5/_static/wwwroot-lib-folder.png b/docs/migrating/migratingfrommvc5/_static/wwwroot-lib-folder.png new file mode 100644 index 000000000000..00832dc7253c Binary files /dev/null and b/docs/migrating/migratingfrommvc5/_static/wwwroot-lib-folder.png differ diff --git a/docs/migrating/migratingfrommvc5/migratingfrommvc5.rst b/docs/migrating/migratingfrommvc5/migratingfrommvc5.rst new file mode 100644 index 000000000000..71598ff12df9 --- /dev/null +++ b/docs/migrating/migratingfrommvc5/migratingfrommvc5.rst @@ -0,0 +1,259 @@ +Migrating From ASP.NET MVC 5 to MVC 6 +===================================== +By `Steve Smith`_ | Originally Published: 1 June 2015 + +.. _`Steve Smith`: Author_ + +Migrating from ASP.NET MVC 5 to ASP.NET 5 and MVC 6 requires a few steps to complete, since ASP.NET 5 introduces a number of new concepts. In this article you will learn how to migrate from the ASP.NET MVC 5 default project template to ASP.NET MVC 6, including initial setup, basic controllers and views, static content, and client side dependencies. + +This article covers the following topics: + - Create the Initial Project + - Create the Destination Solution + - Migrate Basic Controllers, Views, and Static Content + - Configure Bundling + +You can download the finished source from the project created in this article HERE **(TODO)**. + +Create the Initial Project +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For the purposes of this article, we will be starting from the default ASP.NET MVC 5 starter web project, which you can create in Visual Studio 2015 by adding a new web project and choosing MVC 5. + +.. image:: _static/new-project.png + +.. image:: _static/new-project-select-mvc-template.png + +If you prefer, you can `download the MVC 5 Project used in this article `_. **(TODO)** + +This sample web project will demonstrate how to migrate an MVC 5 web project that includes controllers, views, and ASP.NET Identity models, as well as startup and configuration logic common to many MVC 5 projects. + +Create the Destination Solution +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We will begin our migration by creating a new, empty ASP.NET 5 solution. Create a new project in Visual Studio 2015, choose an ASP.NET Web Application, and then choose the ASP.NET 5 Empty template. + +.. image:: _static/new-project-mvc6.png + +.. image:: _static/new-project-select-empty-aspnet5-template.png + +This migration will start from an empty template. If you're already familiar with ASP.NET 5 and its starter templates and there are features in a starter template you would like to take advantage of, you may wish to start from another template. The next step is to configure the site to use MVC. This requires changes to the project.json file and Startup.cs file. First, open project.json and add "Microsoft.AspNet.Mvc" to the "dependencies" property: + +.. code-block:: javascript + + "dependencies": { + "Microsoft.AspNet.Server.IIS": "1.0.0-beta4", + "Microsoft.AspNet.Mvc": "6.0.0-beta4" + }, + +Now open Startup.cs and modify it as follows: + +.. code-block:: c# + + public void ConfigureServices(IServiceCollection services) + { + services.AddMvc(); + } + + public void Configure(IApplicationBuilder app) + { + app.UseMvc(routes => + { + routes.MapRoute( + name: "default", + template: "{controller=Home}/{action=Index}/{id?}"); + }); + } + +At this point we are ready to create a simple Controller and View. Add a Controllers folder and a Views folder to the project. Add an MVC Controller called HomeController.cs class to the Controllers folder and a Home folder in the Views folder. Finally, add an Index.cshtml MVC View Page to the Views/Home folder. The project structure should be as shown: + +.. image:: _static/project-structure-controller-view.png + +Modify Index.cshtml to show a welcome message: + +.. code-block:: html + +

    Hello world!

    + +Run the application - you should see Hello World output in your browser. + +.. image:: _static/hello-world.png + +Migrate Basic Controllers, Views, and Static Content +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Now that we've confirmed we have a simple, working ASP.NET MVC 6 project, it's time to start migrating functionality from the source project. There are many different ways one can approach this task. We will need to move all of the client-side content files (CSS, fonts, scripts), all of the controllers, views, and models, and migrate configured features like bundling, filters, and identity. Let's begin by replacing our simple "hello world" implementation of HomeController with the actual HomeController and Views from the source project. + +Copy each of the methods from the source HomeController to the HomeController we added to the project in the previous section. Note that in MVC 5, actions typically returned ActionResult, but in MVC 6 this has changed to IActionResult (though it will still compile if you leave it as ActionResult). + +Next, create new MVC View Pages in the Views/Home folder for About and Contact. Copy the contents of the corresponding views in the old project to these new views, as well as Index.cshtml. At this point you should once again be able to run the new application, and although the styles are not yet in place, you should see the correct content on the home page as well as /home/about and /home/contact (contact is shown here): + +.. image:: _static/contact-page.png + +In MVC 5 and previous versions of ASP.NET, static content was hosted from the root of the web project, and was intermixed with server-side files. In MVC 6, all static content files are hosted from the /wwwroot folder, so we will need to adjust where we are storing our static content files. For instance, we can copy the favicon.ico file from the root of the original project to the /wwwroot folder in the new project. + +The MVC 5 project uses Bootstrap for its styling, with files stored in /Content and /Scripts and referenced in /Views/Shared/_Layout.cshtml. We could simply copy the bootstrap.js and bootstrap.css files from the old project to the /wwwroot folder in the new project, but there are better ways to handle these kinds of client-side library dependencies in ASP.NET 5. + +In our new project, we'll add support for Bootstrap (and other client-side libraries), but we'll do so using the new support for client-side build tooling using Bower and grunt. First, add a new Bower JSON Configuration File to the project root, called bower.json. In its "dependencies" property, add bootstrap, jquery, jquery-validation, and jquery-validation-unobtrusive. Add new properties for these items to the "exportsOverride" property as well, so that the complete bower.json file looks like this: + +.. code-block:: javascript + + { + "name": "NewMvc6Project", + "private": true, + "dependencies": { + "bootstrap": "3.0.0", + "jquery": "1.10.2", + "jquery-validation": "1.11.1", + "jquery-validation-unobtrusive": "3.2.2" + }, + "exportsOverride": { + "bootstrap": { + "js": "dist/js/*.*", + "css": "dist/css/*.*", + "fonts": "dist/fonts/*.*" + }, + + "jquery": { + "": "jquery.{js,min.js,min.map}" + }, + "jquery-validation": { + "": "jquery.validate.js" + }, + "jquery-validation-unobtrusive": { + "": "jquery.validate.unobtrusive.{js,min.js}" + } + } + } + +Bower will automatically download the specified dependencies, but for now the files are not yet in the wwwroot folder, and so cannot be requested by the browser: + +.. image:: _static/project-structure-bower.png + +Next, we will configure Grunt to process these files and place them where we want them in the wwwroot folder. First, we need to make sure Grunt is installed locally for the project. This is accomplished using NPM, which is similar to Bower but requires a different configuration file, "package.json". Add a new NPM configuration file to the root of the project, called package.json. Add the "grunt" and "grunt-bower-task" items to the devDependencies property, as shown (you should get Intellisense as you type their names): + +.. code-block:: javascript + + "devDependencies": { + "grunt": "0.4.5", + "grunt-bower-task": "0.4.0" + } + +Save your changes. You should see a new NPM folder in your project, under Dependencies, and it should include the grunt and grunt-bower-task items. + +Next, add a new Grunt Configuration file (Gruntfile.js) to the root of the project. The default version of this file includes an empty call to grunt.initConfig. We need to configure grunt to use bower, and then register tasks associated with this configuration. Modify the Gruntfile.js to match this file: + +.. code-block:: javascript + + module.exports = function (grunt) { + grunt.initConfig({ + bower: { + install: { + options: { + targetDir: "wwwroot/lib", + layout: "byComponent", + cleanTargetDir: false + } + } + } + }); + + grunt.registerTask("default", ["bower:install"]); + + grunt.loadNpmTasks("grunt-bower-task"); + }; + +Now that we've finished setting things up, we're ready to let these tools manage our static files and client-side dependencies for us. Right click on gruntfile.js in your project, and select Task Runner Explorer. Double-click on the bower task to run it. + +.. image:: _static/task-runner-explorer.png + +The output should show that the process completed without errors, and you should see that it copied some packages to the \wwwroot\lib folder. Open the wwwroot\lib folder in project explorer, and you should fine that the client-side dependencies (bootstrap, jquery, etc.) have all been copied into this folder: + +.. image:: _static/wwwroot-lib-folder.png + +The files have minified as well as developer-readable versions available; we will configure bundling shortly. + +Now that the required bootstrap files are available in the wwwroot folder, the next step is to modify our Views to include references to these files. Copy the _ViewStart.cshtml file from the original project's Views folder into the new project's Views folder. In this case, it references /Shared/_Layout.cshtml, which is the next file we need to copy (create a new Shared folder in /Views and copy _Layout.cshtml from the old project to it). Open _Layout.cshtml and make the following changes: + + - Replace @Styles.Render("~/Content/css") with a element to load bootstrap.css (see below) + - Remove @Scripts.Render("~/bundles/modernizr") + - Comment out the line with @Html.Partial("_LoginPartial") - we'll return to it shortly (surround the line with @*...*@) + - Replace @Scripts.Render("~/bundles/jquery") with a + + +The complete _Layout.cshtml file should look like this at the moment: + +.. image:: _static/layout-cshtml.png + +View the site in the browser. It should now load correctly, with the expected styles in place. + +(*TODO - Convert Views/web.config to _GlobalImport.cshtml with @using statements *) + +Configure Bundling +^^^^^^^^^^^^^^^^^^^^^^^^ + +The ASP.NET MVC 5 starter web template utilized ASP.NET's built-in support for bundling. In ASP.NET MVC 6, this functionality is better performed using client build steps, like we have already configured to manage our client-side dependencies. Instead of maintaining bundling functionality in a static configuration class that runs on the server, the minification and combination of files is done as part of the build process, using grunt. + +You can learn more about configuring Grunt here.(*TODO*) + +To simply bundle the jQuery and boostrap scripts together into a single, minified, file, we can use the grunt-contrib-concat task. First, update package.json to require grunt-contrib-concat in "devDependencies": + +.. code-block:: javascript + + "devDependencies": { + "grunt": "0.4.5", + "grunt-bower-task": "0.4.0", + "grunt-contrib-concat": "0.5.1" + } + +Save the package.json file and the new package should be installed. You can confirm by checking in the Dependencies/NPM folder to see that the grunt-contrib-concat package is listed there. Next, we will add a concat task to gruntfile.js (after the bower task, in initConfig): + +.. code-block:: javascript + + concat: { + all: { + src: ['wwwroot/lib/jquery/jquery.min.js', + 'wwwroot/lib/bootstrap/js/bootstrap.min.js' + ], + dest: 'wwwroot/lib/bundle.js' + } + } + +Finally, in order to run the task, you need to call grunt.loadNpmTasks: + +.. code-block:: javascript + + grunt.loadNpmTasks('grunt-contrib-concat'); + +Save gruntfile.js, then open the Task Runner Explorer. Right click on the concat task and run it. You should see the output, which should show that it runs without errors. In your solution explorer, you should see the bundle.js file in wwwroot/lib. You can see all of this working in the screenshot: + +.. image:: _static/updated-gruntfile-with-concat.png + +All that remains it to update _Layout.cshtml and replace the last two + +Refresh the site in a browser, and you can see that the calls to load jQuery.js and bootstrap.js have been replaced with a single call to bundle.js: + +.. image:: _static/bundle-screenshot.png + +Summary +^^^^^^^ + +Migrating from ASP.NET MVC 5 to ASP.NET MVC 6 requires several steps, but is not overly difficult. Basic features like the models, views, and controllers that comprise an MVC application can be migrated largely without changes. Most of the changes affect static content and features related to static content, like bundling, as well as configuration steps for the application. By following the steps in this example, you should be able to quickly migrate most ASP.NET MVC 5 applications. + +.. include:: /_authors/steve-smith.rst