简体   繁体   English

将 Visual Studio 2017 MVC 视图脚手架更新为 Bootstrap 4

[英]Update Visual Studio 2017 MVC View Scaffolding to Bootstrap 4

I've just updated my Visual Studio 2017 ASP.NET MVC 5 application from Bootstrap v3 to v4.我刚刚将我的 Visual Studio 2017 ASP.NET MVC 5 应用程序从 Bootstrap v3 更新到了 v4。 I'm finding when I add a new edit partial view using scaffolding , it is still using the Bootstrap v3 CSS class names for the form.我发现当我使用 scaffolding添加新的编辑部分视图时,它仍然使用 Bootstrap v3 CSS 类名称作为表单。 Is there a way to update the scaffolding to use BS v4?有没有办法更新脚手架以使用 BS v4?

Edit编辑

There seems to be some confusion about what I'm talking about.我在说什么似乎有些混乱。

In Visual Studio 2017, in an MVC project, in Solution Explorer, right click the Views folder > Add > View... > MVC 5 View > Click Add .在 Visual Studio 2017 的 MVC 项目中,在解决方案资源管理器中,右键单击Views folder > Add > View... > MVC 5 View > Click Add

This brings up the Add View dialog.这将打开“添加视图”对话框。 I type my View name, choose the Edit Template and choose, for this example, LoginVm as the Model class.我输入我的视图名称,选择“编辑模板”,并在本示例中选择LoginVm作为模型类。 Visual Studio generates this markup. Visual Studio 生成此标记。 This process is called scaffolding.这个过程称为脚手架。

@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>

Notice the Bootstrap 3 classes in use such as form-label and col-md-offset-2 .请注意正在使用的 Bootstrap 3 类,例如form-labelcol-md-offset-2 These were removed in Bootstrap 4. Similarly, if you were to create a new Layout page, it would generate a Bootstrap 3 Navbar which is invalid in Bootstrap 4.这些在 Bootstrap 4 中被删除了。 同样,如果你要创建一个新的布局页面,它会生成一个 Bootstrap 3 导航栏,这在 Bootstrap 4 中是无效的。

So I'm asking if there is a way (short of writing a custom scaffolder) to update Visual Studio to stop outputting Bootstrap 3 specific markup and, ideally, output Bootstrap 4 markup instead?所以我问是否有办法(除了编写自定义脚手架)更新 Visual Studio 以停止输出 Bootstrap 3 特定标记,理想情况下,输出 Bootstrap 4 标记?

An update is not yet available, however to support the edit view scaffolding with Bootstrap 4 in Visual Studio 2017, You have to edit the file Edit.cs.t4 in "%ProgramFiles%\\Microsoft Visual Studio\\2017\\Community\\Common7\\IDE\\Extensions\\Microsoft\\Web\\Mvc\\Scaffolding\\Templates\\MvcView"尚无更新可用,但要在 Visual Studio 2017 中使用 Bootstrap 4 支持编辑视图脚手架,您必须在“%ProgramFiles%\\Microsoft Visual Studio\\2017\\Community\\Common7\\IDE”中编辑文件 Edit.cs.t4 \\Extensions\\Microsoft\\Web\\Mvc\\Scaffolding\\Templates\\MvcView”

  • Rename the file to "Edit.cs.backup.t4"将文件重命名为“Edit.cs.backup.t4”
  • Create a new file "Edit.cs.t4" and add the following code, this will support new Bootstrap 4 classes and form controls ( Bootstrap custom forms and controls ):创建一个新文件“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" #>

The templates used by the scaffolding engine in VS are fixed. VS 中脚手架引擎使用的模板是固定的。 They are located in your VS install dir (eg %programfiles%\\Microsoft Visual Studio\\2017\\Community\\Common7\\IDE\\Extensions\\Microsoft\\Web\\Mvc\\Scaffolding\\Templates\\MvcView).它们位于您的 VS 安装目录中(例如 %programfiles%\\Microsoft Visual Studio\\2017\\Community\\Common7\\IDE\\Extensions\\Microsoft\\Web\\Mvc\\Scaffolding\\Templates\\MvcView)。

So the Bootstrap 3 classes are fixed in the T4-files provided by MS (current standard is BS3 which is added by default currently when creating a new MVC web project).所以 Bootstrap 3 类在 MS 提供的 T4 文件中是固定的(当前标准是 BS3,当前在创建新的 MVC web 项目时默认添加)。 Just have a look at "Edit.cs.t4" in the dir mentioned above.看看上面提到的目录中的“Edit.cs.t4”。 You will find deprecated BS3 classes like "btn-default" (which is btn-secondary in BS4) in there.您会在其中找到不推荐使用的 BS3 类,例如“btn-default”(在 BS4 中为 btn-secondary)。

You can create your own custom T4-templates if you like.如果您愿意,您可以创建自己的自定义 T4 模板。 The MS ref for this task would be: https://docs.microsoft.com/en-us/visualstudio/modeling/code-generation-and-t4-text-templates此任务的 MS 参考将是: https : //docs.microsoft.com/en-us/visualstudio/modeling/code-generation-and-t4-text-templates

To fix/update the ASP .NET MVC 5 project navbar to Bootstrap 4 you have to update your code manually as follows:要将 ASP .NET MVC 5 项目导航栏修复/更新到 Bootstrap 4,您必须手动更新代码,如下所示:

  • Views -> Shared -> _Layout.cshtml.视图 -> 共享 -> _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>

Then if you don't use the Login partial, you can remove it.然后,如果您不使用 Login 部分,则可以将其删除。 Otherwise, change the _LoginPartial.cshtml to:否则,将 _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> }

And last just remove the next lines from Content/Site.css:最后从 Content/Site.css 中删除下一行:

 /*delete this*/ body { padding-top: 50px; padding-bottom: 20px; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM