Update Visual Studio 2017 MVC View Scaffolding to Bootstrap 4

前端 未结 3 1842
余生分开走
余生分开走 2021-01-04 18:10

I\'ve just updated my Visual Studio 2017 ASP.NET MVC 5 application from Bootstrap v3 to v4. I\'m finding when I add a new edit partial view using scaffolding, it is still us

相关标签:
3条回答
  • 2021-01-04 18:41

    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"

    • Rename the file to "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):

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

    0 讨论(0)
  • 2021-01-04 18:49

    To fix/update the ASP .NET MVC 5 project navbar to Bootstrap 4 you have to update your code manually as follows:

    • Views -> Shared -> _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. Otherwise, change the _LoginPartial.cshtml to:

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

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

    0 讨论(0)
  • 2021-01-04 18:52

    The templates used by the scaffolding engine in VS are fixed. They are located in your VS install dir (e.g. %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). Just have a look at "Edit.cs.t4" in the dir mentioned above. You will find deprecated BS3 classes like "btn-default" (which is btn-secondary in BS4) in there.

    You can create your own custom T4-templates if you like. The MS ref for this task would be: https://docs.microsoft.com/en-us/visualstudio/modeling/code-generation-and-t4-text-templates

    0 讨论(0)
提交回复
热议问题