GrabDuck

Переход с ASP.NET MVC 5 на MVC 6 — Документация ASP.NET MVC 6

:

Rick Anderson, Daniel Roth, Steve Smith и Scott Addie

В этой статье мы расскажем, как начать перенос ASP.NET MVC 5 проекта на ASP.NET MVC 6. Мы расскажем о многих вещах, которые отличают MVC 5 от MVC 6. Переход с MVC 5 на MVC 6 - это многоэтапный процесс, и в этой статье покрываются начальная установка, основные контроллеры и представления, статический контент и зависимости на стороне клиента. Из других статей вы узнаете о миграции моделей ASP.NET Identity, а также о запуске и конфигурации многих MVC 5 проектов.

Чтобы показать обновление, мы создадим новое ASP.NET MVC 5 приложение. Назовем его WebApp1, так что пространство имен будет соответствовать MVC 6 проекту, который мы создадим на следующем этапе.

../_images/new-project1.png ../_images/new-project-select-mvc-template.png

Optional: Измените имя решения с WebApp1 на Mvc5. Visual Studio отобразит имя нового решения (Mvc5), что упростит вызов этого проекта из следующего. Возможно, вам потребуется выйти из Visual Studio и перезагрузить проект, чтобы увидеть новое имя.

Создаем новое empty MVC 6 веб приложение с тем же именем, что и предыдущий проект (WebApp1), так что пространства имен двух проектов соответствуют друг другу. Наличие двух одинаковых пространств имен упрощает копирование кода между двумя проектами. Чтобы проект мог использовать то же имя, вам надо создать его в другой директории, чем предыдущий проект.

../_images/new-project-select-empty-aspnet5-template.png
  • Optional: Создайте новое MVC 6 приложение с именем WebApp1 с аутентификацией Individual User Accounts. Переименуйте это приложение в FullMVC6. Создание такого проекта сэкономит ваше время при конверсии. Вы можете взглянуть на сгенерированный шаблоном код, чтобы увидеть конечный результат, или скопировать код в проект конверсии. Это также полезно, если вы застряли на этапе конверсии при сравнении с проектом, сгенерированным шаблоном.
  • Откройте файл project.json и добавьте Microsoft.AspNet.Mvc и Microsoft.AspNet.StaticFiles в свойство dependencies и раздел scripts, как показано ниже:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
    "version": "1.0.0-*",
    "compilationOptions": {
        "emitEntryPoint": true
    },

    "dependencies": {
        "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
        "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
        "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
        "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final"
    },

    "commands": {
        "web": "Microsoft.AspNet.Server.Kestrel"
    },

    "frameworks": {
        "dnx451": { },
        "dnxcore50": { }
    },

    "exclude": [
        "wwwroot",
        "node_modules"
    ],
    "publishExclude": [
        "**.user",
        "**.vspscc"
    ],
    "scripts": {
        "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ]
    }
}

Microsoft.AspNet.StaticFiles - это обработчик статических файлов. ASP.NET рантайм является модульным, и вы должны делать прямой выбор, чтобы обслуживать статические файлы (см. Working with Static Files).

Раздел scripts используется для обозначения того, когда должны запускаться определенные автоматические скрипты. В Visual Studio теперь есть встроенная поддержка для запуска скриптов до и после определенных событий. В разделе scripts выше определены скрипты NPM, Bower и Gulp, которые должны запускаться на стадии до публикации. Позже мы поговорим о NPM, Bower и Gulp. Обратите внимание на ”,” в конце раздела publishExclude.

См. project.json и Introducing .NET Core.

  • Откройте файл Startup.cs и измените код на следующий:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app)
    {
        app.UseIISPlatformHandler();

        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

UseStaticFiles добавляет обработчик статических файлов. Как упоминалось ранее, ASP.NET рантайм является модульным, и вы должны делать прямой выбор, чтобы обрабатывать статические файлы. См. Запуск приложения и Маршрутизация.

В этом разделе мы добавим контроллер и представление, которые будут служить заменителями для MVC 5 контроллера и представлений, что вы перенесете далее.

  • Добавьте папку Controllers.
  • Добавьте MVC controller class с именем HomeController.cs в папку Controllers.
../_images/add_mvc_ctl.png
  • Добавьте папку Views.
  • Добавьте папку Views/Home.
  • Добавьте MVC представление Index.cshtml в папку Views/Home.
../_images/view.png

Структура проекта показана ниже:

../_images/project-structure-controller-view.png

Замените контекст файла Views/Home/Index.cshtml следующим:

Запустите приложение.

../_images/hello-world.png

См. Контроллеры и Представления.

Теперь у нас есть небольшой работающий MVC 6 проект, и мы можем начать переносить функционал из MVC 5 проекта. Мы должны перенести следующее:

  • контент со стороны клиента (CSS, шрифты и скрипты)
  • контроллеры
  • представления
  • модели
  • механизм связывания
  • фильтры
  • Логин/Логаут, Identity (Это мы сделаем с ледующей статье.)
  • Скопируйте каждый метод из MVC 5 HomeController в MVC 6 HomeController. Обратите внимание, что в MVC 5 метод действия встроенного шаблонного контроллера возвращает тип ActionResult; в MVC 6 шаблоны генерируют методы IActionResult. ActionResult - это единственная реализация IActionResult, так что вам не нужно менять возвращаемый тип методов действия.
  • Удалите представление Views/Home/Index.cshtml из проекта MVC 6.
  • Скопируйте файлы Razor представлений About.cshtml, Contact.cshtml и Index.cshtml из проекта MVC 5 в проект MVC 6.
  • Запустите MVC 6 приложение и протестируйте каждый метод. Мы пока еще не перенесли файл с версткой и стили, так что отображаемые представления будут содержать только контекст файлов представлений. У вас не будет сгенерированных ссылок с версткой для представлений About и Contact, так что вам нужно вызывать их из браузера (заменить 2468 номером порта, который используется в важном проекте).
../_images/contact-page.png

Обратите внимание на отсутствие стилей и элементов меню. Скоро мы это исправим.

В предыдущих версиях MVC (включая MVC 5) статический контент хостился из корневой директории веб проекта и был перемешан с файлами серверной стороны. В MVC 6 статический контент хостится в папке wwwroot. Вы копируете статический контент из вашего MVC 5 приложения в папку wwwroot вашего MVC 6 проекта. Конверсия для данного примера:

  • Скопируйте файл favicon.ico из MVC 5 проекта в папку wwwroot MVC 6 проекта.

В MVC 5 проекте используется Bootstrap для стилизации, и Bootstrap файлы сохраняются в папках Content и Scripts. Сгенерированный по шаблону MVC 5 проект ссылается на Bootstrap в файле с версткой (Views/Shared/_Layout.cshtml). Вы можете скопировать файлы bootstrap.js и bootstrap.css из проекта MVC 5 в папку wwwroot нового проекта, но при данном подходе не используется улучшенный механизм управления зависимостями со стороны клиента в ASP.NET 5.

В новом проекте мы добавим поддержку Bootstrap (и других библиотек клиентской стороны) с помощью Bower:

  • Добавьте в корневую директорию проекта конфигурационный файл Bower с именем bower.json (Кликните правой клавишей мышки по проекту, а затем нажмите Add > New Item > Bower Configuration File). Добавьте Bootstrap и jquery в файл (см. код ниже).
{
    "name": "ASP.NET",
    "private": true,
    "dependencies": {
        "bootstrap": "3.3.5",
        "jquery": "2.1.4"
    }
}

При сохранении файла Bower автоматически скачает зависимости в папку wwwroot/lib. Вы можете использовать Search Solution Explorer, чтобы найти путь к активам.

../_images/search.png

См. Manage Client-Side Packages with Bower.

Когда вы создаете новое приложение с помощью шаблона ASP.NET 5 Web Application, проект настраивается так, чтобы использовать Gulp. Gulp - это система потоковой сборки для кода клиентской стороны (HTML, LESS, SASS и тд.). Включенный gulpfile.js содержит JavaScript, определяющий набор gulp задач, которые могут запускаться автоматически для событий, или вы можете запускать их вручную, используя Task Runner Explorer в Visual Studio. В этом разделе мы покажем вам, как использовать файл MVC 6 gulpfile.js, чтобы связывать и уменьшать JavaScript и CSS файлы в проекте.

Если вы создали дополнительный проект FullMVC6 (новое ASP.NET MVC 6 веб приложение с Individual User Accounts), добавьте gulpfile.js из этого проекта в проект, который мы обновляем. В Solution Explorer кликните правой клавишей по проекту и выберите Add > Existing Item.

../_images/addExisting.png

Перейдите к gulpfile.js из нового ASP.NET MVC 6 приложения с Individual User Accounts и добавьте файл gulpfile.js. Как вариант, кликните правой клавишей мышки по проекту и выберите Add > New Item. Выберите Gulp Configuration File и назовите файл gulpfile.js. Замените контекст gulp файла следующим:

/// <binding Clean='clean' />
"use strict";

var gulp = require("gulp"),
    rimraf = require("rimraf"),
    concat = require("gulp-concat"),
    cssmin = require("gulp-cssmin"),
    uglify = require("gulp-uglify");

var paths = {
    webroot: "./wwwroot/"
};

paths.js = paths.webroot + "js/**/*.js";
paths.minJs = paths.webroot + "js/**/*.min.js";
paths.css = paths.webroot + "css/**/*.css";
paths.minCss = paths.webroot + "css/**/*.min.css";
paths.concatJsDest = paths.webroot + "js/site.min.js";
paths.concatCssDest = paths.webroot + "css/site.min.css";

gulp.task("clean:js", function (cb) {
    rimraf(paths.concatJsDest, cb);
});

gulp.task("clean:css", function (cb) {
    rimraf(paths.concatCssDest, cb);
});

gulp.task("clean", ["clean:js", "clean:css"]);

gulp.task("min:js", function () {
    return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
        .pipe(concat(paths.concatJsDest))
        .pipe(uglify())
        .pipe(gulp.dest("."));
});

gulp.task("min:css", function () {
    return gulp.src([paths.css, "!" + paths.minCss])
        .pipe(concat(paths.concatCssDest))
        .pipe(cssmin())
        .pipe(gulp.dest("."));
});

gulp.task("min", ["min:js", "min:css"]);

В коде сверху выполняются эти функции:

  • Удаляются целевые файлы.
  • Уменьшаются JavaScript и CSS файлы.
  • Связываются JavaScript и CSS файлы.

См. использование Gulp с ASP.NET 5 и Visual Studio.

NPM (Node Package Manager) - это менеджер пакетов, который используется для получения такого инструментария, как Bower и Gulp; и он полностью поддерживается в Visual Studio 2015. Мы будем использовать NPM, чтобы управлять зависимостями Gulp.

Если вы создали дополнительный FullMVC6 проект, добавьте NPM файл package.json из проекта в поект, который мы обновляем. В этом файле перечисляются зависимости для процесса сборки на клиентской стороне, определенного в gulpfile.js. Кликните правой клавишей мышки по проекту, выберите Add > Existing Item и добавьте NPM файл package.json. Как вариант, вы можете добавить новый конфигурационный NPM файл следующим образом:

  1. В Solution Explorer кликните правой клавишей мышки по проекту.
  2. Выберите Add > New Item.
  3. Выберите NPM Configuration File.
  4. Оставьте имя по умолчанию: package.json.
  5. Нажмите Add.

Откройте файл package.json и замените его контекст следующим:

{
  "name": "ASP.NET",
  "version": "0.0.0",
  "devDependencies": {
    "gulp": "3.8.11",
    "gulp-concat": "2.5.2",
    "gulp-cssmin": "0.1.7",
    "gulp-uglify": "1.2.0",
    "rimraf": "2.2.8"
  }
}

Кликните правой клавишей мышки по gulpfile.js и выберите Task Runner Explorer. Дважды кликните по задаче, чтобы запустить ее.

См. Client-Side Development in ASP.NET 5.

  • Скопируйте файл _ViewStart.cshtml из папки Views MVC 5 проекта в папку Views MVC 6 проекта. Файл _ViewStart.cshtml не изменился в MVC 6.
  • Создайте папку Views/Shared.
  • Скопируйте файл _Layout.cshtml из папки MVC 5 проекта Views/Shared в папку MVC 6 проекта Views/Shared.

Откройте файл _Layout.cshtml и внесите следующие изменения (полный код показан ниже):

  • Замените @Styles.Render(“~/Content/css”) элементом <link> для загрузки bootstrap.css (см. ниже)
  • Удалите @Scripts.Render(“~/bundles/modernizr”)
  • Закомментируйте строку @Html.Partial(“_LoginPartial”) (окружите строку @*...*@) - позже мы это тоже рассмотрим
  • Замените @Scripts.Render(“~/bundles/jquery”) элементом <script> (см. ниже)
  • Замените @Scripts.Render(“~/bundles/bootstrap”) элементом <script> (см. ниже)

Замещающая CSS ссылка:

<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />

Замещающие тэги script:

<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>

Обновленный файл _Layout.cshtml показан ниже:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                </ul>
                @*@Html.Partial("_LoginPartial")*@
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>

    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
    @RenderSection("scripts", required: false)
</body>
</html>

Просмотрите сайт в браузере. Сейчас он должен отображаться корректно, со всеми стилями.

В MVC 5 используется рантайм поддержка связывания. В ASP.NET MVC 6 этот функционал выполняется как часть процесса сборки с помощью Gulp. Мы уже раньше настроили связывание и минимизацию; нам осталось только изменить ссылки на Bootstrap, jQuery и другие активы, чтобы они использовали связанные и минимизированные версии. Вы можете увидеть, как это делается, в файле с версткой (Views/Shared/_Layout.cshtml) полного проекта. См. Связывание и минимизация.