Обновление Visual Studio 2017 MVC View Scaffolding до Bootstrap 4
Я только что обновил приложение Visual Studio 2017 ASP.NET MVC 5 с Bootstrap v3 до v4. Я нахожу, что когда я добавляю новое частичное представление редактирования с использованием скаффолдинга, он все еще использует имена классов CSS Bootstrap v3 для формы. Есть ли способ обновить строительные леса для использования BS v4?
редактировать
Кажется, есть некоторая путаница в том, о чем я говорю. В Visual Studio 2017 в проекте MVC в обозревателе решений щелкните правой кнопкой мыши папку "Представления"> "Добавить"> "Показать"> "Представление MVC 5"> нажмите "Добавить". Это вызывает диалог Добавить вид. Я ввожу свое имя просмотра, выбираю Редактировать шаблон и выбираю, для этого примера, LoginVm
как модельный класс. Visual Studio создает эту разметку. Этот процесс называется строительные леса.
@model Demo.ViewModels.LoginVm
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>LoginVm</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.UserName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.UserName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Обратите внимание на используемые классы Bootstrap 3, такие как form-label
а также col-md-offset-2
, Они были удалены в Bootstrap 4. Точно так же, если бы вы создали новую страницу Layout, она бы сгенерировала панель навигации Bootstrap 3, которая недопустима в Bootstrap 4. Поэтому я спрашиваю, есть ли способ (если не считать пользовательский скаффолдер)) обновить Visual Studio, чтобы остановить вывод конкретной разметки Bootstrap 3 и, в идеале, вместо этого выводить разметку Bootstrap 4?
1 ответ
Обновление пока недоступно, однако для поддержки лесов представления редактирования с помощью Bootstrap 4 в Visual Studio 2017 необходимо отредактировать файл Edit.cs.t4 в "%ProgramFiles%\Microsoft Visual Studio\2017\Community\Common7\IDE". \Extensions\Microsoft\Web\Mvc\ Строительные леса \Templates\MvcView"
- Переименуйте файл в "Edit.cs.backup.t4"
- Создайте новый файл "Edit.cs.t4" и добавьте следующий код, он будет поддерживать новые классы Bootstrap 4 и элементы управления форм ( пользовательские формы и элементы Bootstrap):
<#@ template language="C#" HostSpecific="True" #>
<#@ output extension=".cshtml" #>
<#@ include file="Imports.include.t4" #>
@model <#= ViewDataTypeName #>
<#
// "form-control" attribute is only supported for all EditorFor() in System.Web.Mvc 5.1.0.0 or later versions, except for checkbox, which uses a div in Bootstrap
string boolType = "System.Boolean";
Version requiredMvcVersion = new Version("5.1.0.0");
bool isControlHtmlAttributesSupported = MvcVersion >= requiredMvcVersion;
// The following chained if-statement outputs the file header code and markup for a partial view, a view using a layout page, or a regular view.
if(IsPartialView) {
#>
<#
} else if(IsLayoutPageSelected) {
#>
@{
ViewBag.Title = "<#= ViewName#>";
<#
if (!String.IsNullOrEmpty(LayoutPageFile)) {
#>
Layout = "<#= LayoutPageFile#>";
<#
}
#>
}
<h2><#= ViewName#></h2>
<#
} else {
#>
@{
Layout = null;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title><#= ViewName #></title>
</head>
<body>
<#
PushIndent(" ");
}
#>
<#
if (ReferenceScriptLibraries) {
#>
<#
if (!IsLayoutPageSelected && IsBundleConfigPresent) {
#>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
<#
}
#>
<#
else if (!IsLayoutPageSelected) {
#>
<script src="~/Scripts/jquery-<#= JQueryVersion #>.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<#
}
#>
<#
}
#>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<h4><#= ViewDataTypeShortName #></h4>
<hr />
<#
if (isControlHtmlAttributesSupported) {
#>
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<#
} else {
#>
@Html.ValidationSummary(true)
<#
}
#>
<#
foreach (PropertyMetadata property in ModelMetadata.Properties) {
if (property.Scaffold && !property.IsAssociation) {
if (property.IsPrimaryKey) {
#>
@Html.HiddenFor(model => model.<#= property.PropertyName #>)
<#
} else if (!property.IsReadOnly) {
bool isCheckbox = property.TypeName.Equals(boolType);
#>
<div class="form-group">
<#
if (property.IsForeignKey) {
#>
@Html.LabelFor(model => model.<#= property.PropertyName #>, "<#= GetAssociationName(property) #>", htmlAttributes: new { @class = "col-form-label col-lg-2" })
<#
} else if (!isCheckbox) {
#>
@Html.LabelFor(model => model.<#= property.PropertyName #>, htmlAttributes: new { @class = "col-form-label col-lg-2" })
<#
}
#>
<div class="col-lg-10">
<#
if (property.IsForeignKey) {
#>
<#
if (isControlHtmlAttributesSupported) {
#>
@Html.DropDownList("<#= property.PropertyName #>", null, htmlAttributes: new { @class = "form-control" })
<#
} else {
#>
@Html.DropDownList("<#= property.PropertyName #>", String.Empty)
<#
}
#>
<#
} else if (isControlHtmlAttributesSupported) {
if (isCheckbox) {
#>
<div class="custom-control custom-checkbox">
<#
PushIndent(" ");
#>
@Html.EditorFor(model => model.<#= property.PropertyName #>, new { htmlAttributes = new { @class = "custom-control-input" } })
@Html.LabelFor(model => model.<#= property.PropertyName #>, htmlAttributes: new { @class = "custom-control-label" })
<#
} else if (property.IsEnum && !property.IsEnumFlags) {
#>
@Html.EnumDropDownListFor(model => model.<#= property.PropertyName #>, htmlAttributes: new { @class = "form-control" })
<#
} else {
#>
@Html.EditorFor(model => model.<#= property.PropertyName #>, new { htmlAttributes = new { @class = "form-control" } })
<#
}
} else {
#>
@Html.EditorFor(model => model.<#= property.PropertyName #>)
<#
}
#>
<#
if (isControlHtmlAttributesSupported) {
#>
@Html.ValidationMessageFor(model => model.<#= property.PropertyName #>, "", new { @class = "text-danger" })
<#
} else {
#>
@Html.ValidationMessageFor(model => model.<#= property.PropertyName #>)
<#
}
#>
<#
if (isCheckbox && isControlHtmlAttributesSupported) {
PopIndent();
#>
</div>
<#
}
#>
</div>
</div>
<#
}
}
}
#>
<div class="form-group">
<div class="col-lg-10">
<input type="submit" value="Save" class="btn btn-primary">
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
<#
if(IsLayoutPageSelected && ReferenceScriptLibraries && IsBundleConfigPresent) {
#>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
<#
}
#>
<#
else if(IsLayoutPageSelected && ReferenceScriptLibraries) {
#>
<script src="~/Scripts/jquery-<#= JQueryVersion #>.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<#
}
#>
<#
// The following code closes the tag used in the case of a view using a layout page and the body and html tags in the case of a regular view page
#>
<#
if(!IsPartialView && !IsLayoutPageSelected) {
ClearIndent();
#>
</body>
</html>
<#
}
#>
<#@ include file="ModelMetadataFunctions.cs.include.t4" #>
Шаблоны, используемые механизмом скаффолдинга в VS, исправлены. Они находятся в каталоге установки VS (например,%programfiles%\Microsoft Visual Studio\2017\Community\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates\MvcView).
Таким образом, классы Bootstrap 3 зафиксированы в T4-файлах, предоставляемых MS (текущий стандарт - BS3, который в настоящее время добавляется по умолчанию при создании нового веб-проекта MVC). Просто посмотрите на "Edit.cs.t4" в директории, упомянутой выше. Там вы найдете устаревшие классы BS3, такие как "btn-default" (который является btn-вторичным в BS4).
Вы можете создавать свои собственные T4-шаблоны, если хотите. Ссылка MS для этой задачи будет следующей: https://docs.microsoft.com/en-us/visualstudio/modeling/code-generation-and-t4-text-templates
Чтобы исправить / обновить навигационную панель проекта ASP .NET MVC 5 до Bootstrap 4, вам необходимо обновить код вручную следующим образом:
- Просмотры -> Общие -> _Layout.cshtml.
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
@Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target=".navbar-collapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav mr-auto">
<li class="nav-item">@Html.ActionLink("Home", "Index", "Home", null, new { @class = "nav-link" })</li>
<li class="nav-item">@Html.ActionLink("About", "About", "Home", null, new { @class = "nav-link" })</li>
<li class="nav-item">@Html.ActionLink("Contact", "Contact", "Home", null, new { @class = "nav-link" })</li>
</ul>
@Html.Partial("_LoginPartial")
</div>
</div>
</nav>
Затем, если вы не используете частичный вход в систему, вы можете удалить его. В противном случае измените _LoginPartial.cshtml на:
@using Microsoft.AspNet.Identity
@if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm" }))
{
@Html.AntiForgeryToken()
<ul class="nav navbar-nav">
<li class="nav-item">
@Html.ActionLink("Hello " + User.Identity.GetUserName() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage", @class = "nav-link" })
</li>
<li class="nav-item"><a class="nav-link" href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
</ul>
}
}
else
{
<ul class="nav navbar-nav">
<li class="nav-item">@Html.ActionLink("Register", "Register", "Account", routeValues: null, htmlAttributes: new { id = "registerLink", @class = "nav-link" })</li>
<li class="nav-item">@Html.ActionLink("Log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink", @class = "nav-link" })</li>
</ul>
}
И наконец, просто удалите следующие строки из Content/Site.css:
/*delete this*/
body {
padding-top: 50px;
padding-bottom: 20px;
}