[ASP.NET MVC 小牛之路]17 - 捆绑(Bundle)

2023-12-22 15:20
文章标签 mvc 17 asp net bundle 捆绑 小牛

本文主要是介绍[ASP.NET MVC 小牛之路]17 - 捆绑(Bundle),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文介绍 MVC 4 提供的一个新特性:捆绑(Bundle),一个在  View 和 Layout 中用于组织优化浏览器请求的 CSS 和 JavaScript 文件的技术。

本文目录

了解VS默认加入的脚本库

当我们创建一个基本模板的 MVC 工程时,VS在Scripts文件夹中默认加入了一些 JavaScript 脚本库。下面是这些脚本库的简单介绍:

  • jquery-1.8.2.js,这个就不用解释了。
  • jquery-ui-1.8.24.js,在jQuery 基础上的一套界面工具,包括了网页上常见的很多插件和动画特效。
  • jquery.validate.js,用于验证用户在表单内input元素输入的数据。
  • knockout-2.2.0.js,是一个轻量级的UI类库,通过应用MVVM模式使JavaScript前端UI简单化,更多:http://knockoutjs.com/documentation/introduction.html。
  • modernizr-2.6.2.js,一个开源的JS库,它使得那些基于访客浏览器的不同(指对新标准支持性的差异)而开发不同级别体验的设计师的工作变得更为简单。它使得设计师可以在支持HTML5和CSS3的浏览器中充分利用HTML5和CSS3的特性进行开发,同时又不会牺牲其他不支持这些新技术的浏览器的控制。更多:http://www.mhtml5.com/2011/03/676.html 。
  • jquery.unobtrusive-ajax.js,MVC 框架中使用 Unobtrusive Ajax 的库,更多:[ASP.NET MVC 小牛之路]14 - Unobtrusive Ajax 。
  • jquery.validate.unobtrusive.js,基于 jquery.unobtrusive-ajax.js,更多:[ASP.NET MVC 小牛之路]15 - Model Binding 。

另外还有一个 _references.js 文件,它的作用是通过下面这种方式放入该文件中的JS文件可以被VS智能感知:

/// <reference path="jquery-1.8.2.js" />
/// <reference path="jquery-ui-1.8.24.js" />

相关小技巧:在VS中让一个JS文件智能提示另一个JS文件中的成员 。

在实际的项目中,我们可能远远不止引入上面这些脚本文件,MVC 4提供的“捆绑”新功能可以很方便地对引入的脚本文件进行管理。

准备工作

选择基本模板创建一个MVC工程。和前一篇的示例差不多,创建一个名为 Appointment 的 Model,代码如下:

public class Appointment {[Required]public string ClientName { get; set; }[DataType(DataType.Date)]public DateTime Date { get; set; }public bool TermsAccepted { get; set; }
}
Appointment

添加一个 HomeController,代码如下:

public class HomeController : Controller {public ViewResult MakeBooking() {return View();}[HttpPost]public JsonResult MakeBooking(Appointment appt) {return Json(appt, JsonRequestBehavior.AllowGet);}
}
HomeController

给MakeBooking action添加一个 MakeBooking.cshtml 视图,代码如下:

@model MvcApplication1.Models.Appointment
@{AjaxOptions ajaxOpts = new AjaxOptions {OnSuccess = "processResponse"};
}
<h4>Book an Appointment</h4><script src="~/Scripts/Home/MakeBooking.js"></script><div id="formDiv" class="visible">@using (Ajax.BeginForm(ajaxOpts)) {@Html.ValidationSummary(true)<p>@Html.ValidationMessageFor(m => m.ClientName)</p><p>Your name: @Html.EditorFor(m => m.ClientName)</p><p>@Html.ValidationMessageFor(m => m.Date)</p><p>Appointment Date: @Html.EditorFor(m => m.Date)</p><p>@Html.ValidationMessageFor(m => m.TermsAccepted)</p><p>@Html.EditorFor(m => m.TermsAccepted) I accept the terms & conditions</p><input type="submit" value="Make Booking" />}
</div>
<div id="successDiv" class="hidden"><h4>Your appointment is confirmed</h4><p>Your name is: <b id="successClientName"></b></p><p>The date of your appointment is: <b id="successDate"></b></p><button id="backButton">Back</button>
</div>

把该视图需要的 JavaScript 代码放在一个单独的文件 MakeBooking.js 中,并将该JS文件放在 /Scripts/Home 文件夹下,该JS文件代码如下:

function processResponse(appt) { $('#successClientName').text(appt.ClientName);$('#successDate').text(processDate(appt.Date));switchViews();
}
function processDate(dateString) {var date = new Date(parseInt(dateString.substr(6, dateString.length - 8)));return date.toLocaleDateString();
}
function switchViews() {var hidden = $('.hidden');var visible = $('.visible');hidden.removeClass("hidden").addClass("visible");visible.removeClass("visible").addClass("hidden");
}
$(document).ready(function () {$('#backButton').click(function (e) {switchViews();});
});
MakeBooking.js

注意,这里需要对后台通过Json方法返回的日期进行处理,Json 方法返回的日期格式是:/Date(1385308800000)/,所以把它呈现给客户端时用 processDate JS方法处理了一下。

在 Content 文件夹下添加一个样式文件 CustomStyles.css,代码如下:

div.hidden { display: none;} 
div.visible { display: block;}

最后清理一下 _Layout.cshtml 文件,如下:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><meta name="viewport" content="width=device-width" /><title>@ViewBag.Title</title>
</head>
<body>@RenderBody()
</body>
</html>
_Layout.cshtml

本文将关心的是 JS 和 CSS 文件的引用,大家不用关心代码本身,此时只需Copy好代码,一会使用捆绑让它运行起来。 

使用捆绑管理脚本和样式文件

以前我们引入脚本和样式文件的时候,都是一个个的引用,看起来一大坨,不小心还会弄错先后次序,管理很是不便。而且很多脚本库有普通和 min 两个版本,开发的时候我们引入普通版本以方便调试,发布的时候又换成min版本以减少网络带宽,很是麻烦。为此,MVC 4 增加了一个新功能:“捆绑”,它的作用是把一类脚本或样式文件捆绑在一起,在需要用的时候调用一句代码就行,极大地方便了脚本和样式文件的管理;而且可以把脚本的普通和 min 两个版本都捆绑起来,MVC也会根据是否为Debug模式智能地选择脚本文件的版本。下面我们来看看这个捆绑功能的使用。

用捆绑方便之一是可以在 /App_Start/BundleConfig.cs 中通过注册来统一管理脚本和样式文件。我们可以打开 BundleConfig.cs 文件看看VS 已经默认对脚本和样式文件的捆绑情况。为了演示如何使用捆绑,我们把VS默认的捆绑代码删除,再增加我们需要的捆绑,如下所示:

public class BundleConfig {public static void RegisterBundles(BundleCollection bundles) {bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/*.css"));bundles.Add(new ScriptBundle("~/bundles/clientfeaturesscripts").Include("~/Scripts/jquery-{version}.js","~/Scripts/jquery.validate.js","~/Scripts/jquery.validate.unobtrusive.js","~/Scripts/jquery.unobtrusive-ajax.js"));}
}

捆绑是通过 RegisterBundles 参数对象的 Add 方法添加。Add 方法的参数需要一个ScriptBundle 类 或 StyleBundle 类的实例对象, 脚本文件用的是 ScriptBundle 类,样式文件用的是 StyleBundle 类,它们的构造参数代表着捆绑在一起的文件的引用。 Include 方法用于包含具体要捆绑的文件。其中的 {version} 是文件版本的占位符,MVC会在相应的目录下定位到最新的一个版本文件。

使用捆绑方便之二是再也不用引入一大坨的文件了,如下面的 _Layout.cshtml:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><meta name="viewport" content="width=device-width" /><title>@ViewBag.Title</title>@Styles.Render("~/Content/css")
</head>
<body>@Scripts.Render("~/bundles/clientfeaturesscripts")@RenderBody()
</body>
</html>

这里通过 @Scripts.Render 和 @Styles.Render 两个Helper方法添加捆绑。需要注意的是,MakeBooking.cshtml 文件引入的 MakeBooking.js 是基于 jQuery的,所以 _Layout.cshtml的 @Scripts.Render("~/bundles/clientfeaturesscripts") 必须放在 @RenderBody() 之前。

使用脚本 Section

上面我们提到在 _Layout.cshtml 中,@Scripts.Render("~/bundles/clientfeaturesscripts") 必须放在 @RenderBody() 之前,因为View引入的JS是基本jQuery的。有时候由于某种需求或个人的喜好要把 @RenderBody() 放在 @Scripts.Render("~/bundles/clientfeaturesscripts") 之前,如果这样的话,MakeBooking.js 文件就在jQuery库之前引用了,显然JS会报错。

对于这种情况,我们可以用 [ASP.NET MVC 小牛之路]12 - Section、Partial View 和 Child Action 文章介绍的Section来解决这种JS引用次序的问题。如下,我们可以把 MakeBooking.cshtml 中引入JS的部分用section包起来:

...
<h4>Book an Appointment</h4> 
@section scripts { <script src="~/Scripts/Home/MakeBooking.js" type="text/javascript"></script> 
} 
...

然后我们就可以在 _Layout.cshtml 所有Render方法后面使用  @RenderSection("scripts", required: false) 方法引入MakeBooking.js 文件,这样就不用关心在 _Layout.cshtml 中的 @RenderBody() 和 @Scripts.Render("~/bundles/clientfeaturesscripts") 的先后次序了。如下所示:

<body> @RenderBody() @Scripts.Render("~/bundles/clientfeaturesscripts") @RenderSection("scripts", required: false) 
</body> 

这样保证了 MakeBooking.js 一定在jQuery库文件之后引用。

使用捆绑带来的改变

捆绑除了可以方便地管理脚本和样式文件,还可以给网络减少带宽。

以下是在Debug模式下使用捆绑MVC生成引用部分的代码:

<link href="/Content/CustomStyles.css" rel="stylesheet"/>
<link href="/Content/Site.css" rel="stylesheet"/>
...
<script src="/Scripts/jquery-1.8.2.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
...
<script src="/Scripts/Home/MakeBooking.js"></script>

总共 7 个文件,在Debug模式下使用捆绑和不使用捆绑没什么区别。

下面我们来比较一下在发布模式下不使用捆绑和使用捆绑两者使用带宽的情况。

在 Web.config 中把调式模式关闭,如下:

...
<system.web><httpRuntime targetFramework="4.5" /><compilation debug="false" targetFramework="4.5" />
...

我们先来看看不使用捆绑使用带宽的情况,为此,我们 MakeBooking.cshtml 中的section部分 和 _Layout.cshtml 中的引用捆绑的部分注释掉。并在 _Layout.cshtml 中引入上面 7 个文件,如下:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><meta name="viewport" content="width=device-width" /><title>@ViewBag.Title</title>@*@Styles.Render("~/Content/css")*@<link href="~/Content/CustomStyles.css" rel="stylesheet"/>    <link href="~/Content/Site.css" rel="stylesheet" /><script src="~/Scripts/jquery-1.8.2.js"></script><script src="~/Scripts/jquery.unobtrusive-ajax.js"></script><script src="~/Scripts/jquery.validate.js"></script><script src="~/Scripts/jquery.validate.unobtrusive.js"></script><script src="~/Scripts/Home/MakeBooking.js"></script>
</head>
<body>@RenderBody()@*@Scripts.Render("~/bundles/clientfeaturesscripts")@RenderSection("scripts", required: false)*@
</body>
</html>

运行程序,用IE F12 工具查看请求服务器资源的情况(注意要先清理缓存),结果如下:

我们看到在不使用捆绑的情况下,客户端接收的数据总大小为330.65 KB。

我们再来看看使用捆绑带宽的使用情况。我们把之前在 MakeBooking.cshtml 和 _Layout.cshtml 中的注释去掉,并把 _Layout.cshtml 引入 7 个文件的代码删除。

运行程序(注意清涂缓存),结果如下:

我们看到,使用捆绑客户端接收的数据总大小为 124.01 KB,和不使用捆绑相比少200多KB,即一半多,这是非常可观的。

我们也注意到,使用捆绑请求的链接也少了。这是因为在发布模式下,响应客户端请求时,MVC整合并最小化了JavaScript文件和样式文件,并使得一个捆绑中的内容在一个请求中加载。如果我们查看Html代码,可以看到 Styles.Render 和 Scripts.Render 两个方法生成了这样的HTML引用代码:

<link href="/Content/css?v=6jdfBoUlZKSHjUZCe_rkkh4S8jotNCGFD09DYm7kBWE1" rel="stylesheet"/>
...
<script src="/bundles/clientfeaturesscripts?v=KyclumLmAXQGM1-wDTwVUS31lpYigmXXR8HfERBGk_I1"></script>
..
<script src="/Scripts/Home/MakeBooking.js"></script>

一个Styles.Render 或 Scripts.Render 方法生成了一个带有v参数的URL,这个URL将使MVC把一整个捆绑的数据进行最小化处理并一次发送到客户端。

 


参考:《Pro ASP.NET MVC 4 4th Edition》

这篇关于[ASP.NET MVC 小牛之路]17 - 捆绑(Bundle)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/524460

相关文章

17.用300行代码手写初体验Spring V1.0版本

1.1.课程目标 1、了解看源码最有效的方式,先猜测后验证,不要一开始就去调试代码。 2、浓缩就是精华,用 300行最简洁的代码 提炼Spring的基本设计思想。 3、掌握Spring框架的基本脉络。 1.2.内容定位 1、 具有1年以上的SpringMVC使用经验。 2、 希望深入了解Spring源码的人群,对 Spring有一个整体的宏观感受。 3、 全程手写实现SpringM

Windows中,.net framework 3.5安装

安装.net framework,目前已知2种方法,如下: 一、在MSDN下载对应的安装包,安装,这种可能无法安装成功,概率很大,不成功使用第二种方法,基本上没问题。 二、win8/8.1/10 下安装 .net framework 3.5.1: 1. 打开 win8/8.1/10 安装盘(这里指系统安装镜像文件),提取 sources\sxs 文件夹到 X:\sources\sxs (X代

BD错误集锦8——在集成Spring MVC + MyBtis编写mapper文件时需要注意格式 You have an error in your SQL syntax

报错的文件 <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.yuan.dao.YuanUserDao"><!

BD错误集锦7——在集成Spring MVC + MyBtis时使用c3p0作为数据库时报错Method com/mchange/v2/c3p0/impl/NewProxyPreparedStatem

异常信息如下: Type Exception ReportMessage Handler dispatch failed; nested exception is java.lang.AbstractMethodError: Method com/mchange/v2/c3p0/impl/NewProxyPreparedStatement.isClosed()Z is abstractDescr

ASP.Net.WebAPI和工具PostMan

1.WebAPI概述 1.1 WebAPI WebAPI 是一种传统的方式,用于构建和暴露 RESTUI风格的Web服务。它提供了丰富的功能和灵活性,可以处理各种HTTP请求,并支持各种数据格式,如JSON、XML等。 WebAPI使用控制器(Controllers)和动作方法(ActionMethods)的概念、通过路由配置将请求映射到相应的方法上。 开发人员可以使用各种属性和过滤器来处

【Qt6.3 基础教程 17】 Qt布局管理详解:创建直观和响应式UI界面

文章目录 前言布局管理的基础为什么需要布局管理器? 盒布局:水平和垂直排列小部件示例:创建水平盒布局 栅格布局:在网格中对齐小部件示例:创建栅格布局 表单布局:为表单创建标签和字段示例:创建表单布局 调整空间和伸缩性示例:增加弹性空间 总结 前言 当您开始使用Qt设计用户界面(UI)时,理解布局管理是至关重要的。布局管理不仅关系到UI的外观,更直接影响用户交互的体验。本篇博

【ASP.NET】 No 'Access-Control-Allow-Origin' header is present on the requested resource.

前端JS用XMLHttpRequest,请求后端数据。出现了No ‘Access-Control-Allow-Origin’ header is present on the requested resource. 我是使用的ASP.NET框架。 解决办法: 在Web.config文件相应地方添加: <?xml version="1.0" encoding="utf-8"?><confi

【鸿蒙】ERROR_GET_BUNDLE_INSTALLER_FAILED

错误信息 [ERROR_GET_BUNDLE_INSTALLER_FAILED] Troubleshooting guide $ hdc file send D:\Huawei\devEcoProjects\entry\build\default\outputs\default\entry-default-unsigned.hap /sdcard/e8a215ea7be1444197e6a58e

Spring MVC的核心类和注解——@RequestMapping注解(二)@RequestMapping注解的属性

一、@RequestMapping注解的属性 属性名 类型 描述 name String 可选属性,用于为映射地址指定别名。 value String[] 可选属性,也是默认属性,用于指定请求的URL。 method RequestMethod[] 可选属性,用于指定该方法可以处理哪种类型的请求方式。 params String[] 可选属性,用于指定客户端请求中参数的值,必须包含

spring mvc完整项目创建步骤记录

快速创建一个spring mvc项目(只有页面调用→到controller→到页面) 1、首先创建Dynamic Web Project 2、创建jsp页面index.jsp以及成功(/WEB-INF/view/success.jsp)和失败页面(/WEB-INF/view/error.jsp) index.jsp <%@ page language="java" contentType=