Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
При работе с ASP.NET Core MVC Visual Studio поддерживает такую функциональность как Scaffolding или шаблоны формирования/генерации кода контроллеров и представлений. Эта функциональность позволяет упростить создание контроллеров и представлений с помощью встроенных шаблонов. Однако по умолчанию эта опция недоступна.
Для ее подключения для конкретного проекта необходимо добавить в проект две зависимости: Microsoft.VisualStudio.Web.CodeGeneration.Tools и Microsoft.VisualStudio.Web.CodeGenerators.Mvc. Так, добавим эти зависимости в секцию dependencies в файле project.json в проекте ASP.NET Core:
"dependencies": { "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { "version": "1.0.0-preview2-final", "type": "build" }, "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": { "version": "1.0.0-preview2-final", "type": "build" }, // остальные зависимости },
Кроме того, изменим секцию tools для регистрации первого пакета:
"tools": { "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { "version": "1.0.0-preview2-final", "imports": [ "portable-net45+win8+dnxcore50", "portable-net45+win8" ] }, //.......................... },
Сохраним файл для применения изменений.
После этого мы можем воспользоваться функциональностью шаблонов. В частности, при добавлении элемента в папку представлений нам становиться доступным опция View:
При выборе пункта View нам откроется специальное окно для настройки создаваемого представления:
Окно содержит несколько полей:
View Name: имя файла представления
Template: шаблон для генерации представления. Имеется ряд шаблонов:
Create: создает разметку для создания модели
Delete: шаблон разметки для удаления модели
Details: шаблон для вывода детального описания модели
Edit: шаблон для редактирования модели
List: шаблон для вывода списка объектов
Model class: класс модели, которая используется в выше рассмотренных шаблонах
Create as a partial view: должно ли представление быть частичным
Reference script libraries: надо добавлять некоторые дополнительные скрипты в представление
Use a layout page: должно ли представление использовать мастер-страницу Layout. Если это поле отмечено, то внизу в текстовом поле мы можем указать какой именно файл будет использоваться в качестве мастер-страницы.
К примеру для модели Phone по шаблону Create генерируется такое представление:
@model RazorApp.Models.Phone @{ ViewData["Title"] = "Create"; } <h2>Create</h2> <form asp-action="Create"> <div class="form-horizontal"> <h4>Phone</h4> <hr /> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="Title" class="col-md-2 control-label"></label> <div class="col-md-10"> <input asp-for="Title" class="form-control" /> <span asp-validation-for="Title" class="text-danger" /> </div> </div> <div class="form-group"> <label asp-for="Company" class="col-md-2 control-label"></label> <div class="col-md-10"> <input asp-for="Company" class="form-control" /> <span asp-validation-for="Company" class="text-danger" /> </div> </div> <div class="form-group"> <label asp-for="Price" class="col-md-2 control-label"></label> <div class="col-md-10"> <input asp-for="Price" class="form-control" /> <span asp-validation-for="Price" class="text-danger" /> </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Create" class="btn btn-default" /> </div> </div> </div> </form> <div> <a asp-action="Index">Back to List</a> </div> @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} }
При нажатии на папку контроллеров правой кнопкой мыши нам становится также доступна опция генерации контроллеров:
При выборе этой опции мы можем выбрать один из следующих вариантов:
MVC Controller - Empty: создает стандартный пустой контроллер
MVC Controller with read/write actions: создает контроллер с набором стандартных методов Index/Details/Create/Edit/Delete, но без конкретной реализации
MVC Controller with views, using Entity Framework: создает контроллер с методами для вывода, добавления, удаления и редактирования модели с использованием Entity Framework
API Controller - Empty: создает пустой контроллер в стиле Web API
API Controller with read/write actions
API Controller with views, using Entity Framework
При выборе шаблона "MVC Controller with views, using Entity Framework" откроется дополнительное окно для настройки контроллера:
Здесь мы можем указать следующие опции:
Model class: класс модели, которой будет управлять контроллер
Data context class: класс контекста данных Entity Framework, который будет использоваться для работы с данными в контроллере
Generate views: позволяет сгенерировать все необходимые представления для методов контроллера
Reference script libraries: надо ли добавлять в представления некоторые дополнительные скрипты
Use a layout page: будут ли создаваемые представления использовать мастер-страницу. Если опция отмечена, можно выбрать конкретную мастер-страницу
Controller name: имя создаваемого контроллера
Фактически эта опция позволяет создать полноценный контроллер со всеми представлениями. Так, если бы мы выбрали данную опцию, то был создан контроллер наподобие следующего:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; using MobileStore.Models; namespace MobileStore.Controllers { public class PhonesController : Controller { private readonly MobileContext _context; public PhonesController(MobileContext context) { _context = context; } public async Task<IActionResult> Index() { return View(await _context.Phones.ToListAsync()); } public async Task<IActionResult> Details(int? id) { if (id == null) { return NotFound(); } var phone = await _context.Phones.SingleOrDefaultAsync(m => m.Id == id); if (phone == null) { return NotFound(); } return View(phone); } public IActionResult Create() { return View(); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([Bind("Id,Company,Name,Price")] Phone phone) { if (ModelState.IsValid) { _context.Add(phone); await _context.SaveChangesAsync(); return RedirectToAction("Index"); } return View(phone); } public async Task<IActionResult> Edit(int? id) { if (id == null) { return NotFound(); } var phone = await _context.Phones.SingleOrDefaultAsync(m => m.Id == id); if (phone == null) { return NotFound(); } return View(phone); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Edit(int id, [Bind("Id,Company,Name,Price")] Phone phone) { if (id != phone.Id) { return NotFound(); } if (ModelState.IsValid) { try { _context.Update(phone); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!PhoneExists(phone.Id)) { return NotFound(); } else { throw; } } return RedirectToAction("Index"); } return View(phone); } public async Task<IActionResult> Delete(int? id) { if (id == null) { return NotFound(); } var phone = await _context.Phones.SingleOrDefaultAsync(m => m.Id == id); if (phone == null) { return NotFound(); } return View(phone); } [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<IActionResult> DeleteConfirmed(int id) { var phone = await _context.Phones.SingleOrDefaultAsync(m => m.Id == id); _context.Phones.Remove(phone); await _context.SaveChangesAsync(); return RedirectToAction("Index"); } private bool PhoneExists(int id) { return _context.Phones.Any(e => e.Id == id); } } }
А в папке представлений был бы автоматически создан подкаталог для представлений для данного контроллера.