别总以为asp.net mvc比asp.net web form好--web form的页面也可以体积小巧

简介: 最近才看到网上有一种对asp.net web form的误解。也有很多讨论,弄得微软ScottGu也来澄清。asp.net mvc和web form是并行存在的两种开发模式。许多人对web form的诟病很多,其中最主要的就是说viewstate,随便一个web form页面,其html源码就体积很大,主要是隐藏字段viewstate体积比较大,至少几十K,页面复杂一点,viewstate的大小能上几兆,这样大体积的页面,在浏览器和服务器之间传输,对网络带宽也是一个很大的压力,所以asp.net webform的性能肯定受很大影响。

最近才看到网上有一种对asp.net web form的误解。也有很多讨论,弄得微软ScottGu也来澄清。asp.net mvc和web form是并行存在的两种开发模式。许多人对web form的诟病很多,其中最主要的就是说viewstate,随便一个web form页面,其html源码就体积很大,主要是隐藏字段viewstate体积比较大,至少几十K,页面复杂一点,viewstate的大小能上几兆,这样大体积的页面,在浏览器和服务器之间传输,对网络带宽也是一个很大的压力,所以asp.net webform的性能肯定受很大影响。这其实是一个对asp.net web form的特大误解。这里提供一个小技巧。可以让asp.net web form的页面和asp.net mvc的页面一样体积小巧。同时还能享受viewstate带来的好处。

举例来说:一个显示记录列表的form。如下图:

 这是一个很简单的页面了。其html源代码是:

 
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
 
</title>
</head>
<body>
    <form method="post" action="Default.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTE5MTIyNjE4Mg9kFgJmD2QWAgIDD2QWAgIBD2QWAgIDDzwrABECAA8WBB4LXyFEYXRhQm91bmRnHgtfIUl0ZW1Db3VudALCA2QMFCsABxYIHgROYW1lBQlBZGRyZXNzSUQeCklzUmVhZE9ubHloHgRUeXBlGSsBHglEYXRhRmllbGQFCUFkZHJlc3NJRBYIHwIFDEFkZHJlc3NMaW5lMR8DaB8EGSsCHwUFDEFkZHJlc3NMaW5lMRYIHwIFDEFkZHJlc3NMaW5lMh8DaB8EGSsCHwUFDEFkZHJlc3NMaW5lMhYIHwIFBENpdHkfA2gfBBkrAh8FBQRDaXR5FggfAgUNU3RhdGVQcm92aW5jZR8DaB8EGSsCHwUFDVN0YXRlUHJvdmluY2UWCB8CBQ1Db3VudHJ5UmVnaW9uHwNoHwQZKwIfBQUNQ291bnRyeVJlZ2lvbhYIHwIFClBvc3RhbENvZGUfA2gfBBkrAh8FBQpQb3N0YWxDb2RlFgJmD2QWDAIBD2QWDmYPDxYCHgRUZXh0BQE5ZGQCAQ8PFgIfBgURODcxMyBZb3NlbWl0ZSBDdC5kZAICDw8WAh8GBQYmbmJzcDtkZAIDDw8WAh8GBQdCb3RoZWxsZGQCBA8PFgIfBgUKV2FzaGluZ3RvbmRkAgUPDxYCHwYFDVVuaXRlZCBTdGF0ZXNkZAIGDw8WAh8GBQU5ODAxMWRkAgIPZBYOZg8PFgIfBgUCMTFkZAIBDw8WAh8GBRMxMzE4IExhc2FsbGUgU3RyZWV0ZGQCAg8PFgIfBgUGJm5ic3A7ZGQCAw8PFgIfBgUHQm90aGVsbGRkAgQPDxYCHwYFCldhc2hpbmd0b25kZAIFDw8WAh8GBQ1Vbml0ZWQgU3RhdGVzZGQCBg8PFgIfBgUFOTgwMTFkZAIDD2QWDmYPDxYCHwYFAjI1ZGQCAQ8PFgIfBgUQOTE3OCBKdW1waW5nIFN0LmRkAgIPDxYCHwYFBiZuYnNwO2RkAgMPDxYCHwYFBkRhbGxhc2RkAgQPDxYCHwYFBVRleGFzZGQCBQ8PFgIfBgUNVW5pdGVkIFN0YXRlc2RkAgYPDxYCHwYFBTc1MjAxZGQCBA9kFg5mDw8WAh8GBQIyOGRkAgEPDxYCHwYFEDkyMjggVmlhIERlbCBTb2xkZAICDw8WAh8GBQYmbmJzcDtkZAIDDw8WAh8GBQdQaG9lbml4ZGQCBA8PFgIfBgUHQXJpem9uYWRkAgUPDxYCHwYFDVVuaXRlZCBTdGF0ZXNkZAIGDw8WAh8GBQU4NTAwNGRkAgUPZBYOZg8PFgIfBgUCMzJkZAIBDw8WAh8GBREyNjkxMCBJbmRlbGEgUm9hZGRkAgIPDxYCHwYFBiZuYnNwO2RkAgMPDxYCHwYFCE1vbnRyZWFsZGQCBA8PFgIfBgUGUXVlYmVjZGQCBQ8PFgIfBgUGQ2FuYWRhZGQCBg8PFgIfBgUHSDFZIDJINWRkAgYPDxYCHgdWaXNpYmxlaGRkGAEFJGN0bDAwJENvbnRlbnRQbGFjZUhvbGRlcjEkZ3JkQWRkcmVzcw88KwAMAQgCWmTq1MHx+5oLH4bMzg2GUy0MyKZQYkR2RY+bxLLJQFR/nQ==" />
</div>
 
<script type="text/javascript"> 
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
    theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
//]]>
</script>
 
 
    <div>
        
    <span id="ContentPlaceHolder1_Label1">My label</span>
<div>
	<table cellspacing="0" rules="all" border="1" id="ContentPlaceHolder1_grdAddress" style="border-collapse:collapse;">
		<tr>
			<th scope="col">AddressID</th><th scope="col">AddressLine1</th><th scope="col">AddressLine2</th><th scope="col">City</th><th scope="col">StateProvince</th><th scope="col">CountryRegion</th><th scope="col">PostalCode</th>
		</tr><tr>
			<td>9</td><td>8713 Yosemite Ct.</td><td> </td><td>Bothell</td><td>Washington</td><td>United States</td><td>98011</td>
		</tr><tr>
			<td>11</td><td>1318 Lasalle Street</td><td> </td><td>Bothell</td><td>Washington</td><td>United States</td><td>98011</td>
		</tr><tr>
			<td>25</td><td>9178 Jumping St.</td><td> </td><td>Dallas</td><td>Texas</td><td>United States</td><td>75201</td>
		</tr><tr>
			<td>28</td><td>9228 Via Del Sol</td><td> </td><td>Phoenix</td><td>Arizona</td><td>United States</td><td>85004</td>
		</tr><tr>
			<td>32</td><td>26910 Indela Road</td><td> </td><td>Montreal</td><td>Quebec</td><td>Canada</td><td>H1Y 2H5</td>
		</tr><tr>
			<td colspan="7"><table>
				<tr>
					<td><span>1</span></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$2')">2</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$3')">3</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$4')">4</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$5')">5</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$6')">6</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$7')">7</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$8')">8</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$9')">9</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$10')">10</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$11')">...</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$Last')">>></a></td>
				</tr>
			</table></td>
		</tr>
	</table>
</div>
<br />
 
    </div>
    </form>
</body>
</html>

可见其隐藏字段viewstate体积较大。对应用程序的性能会有较大影响。 

通过如下方法,可以让页面html源代码体积变小巧。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EntLibSample
{
    public class BasePage : System.Web.UI.Page
    {
        protected override void SavePageStateToPersistenceMedium(object viewState)
        {
            Session["viewState" + this.Context.Request.FilePath] = viewState;
        }

        protected override object LoadPageStateFromPersistenceMedium()
        {
            if (Session["viewState" + this.Context.Request.FilePath] != null)
            {
                return Session["viewState" + this.Context.Request.FilePath];
            }
            return string.Empty;
        }
    }
}

这个BasePage类继承了System.Web.UI.Page类。System.Web.UI.Page中的SavePageStateToPersistenceMedium和LoadPageStateFromPersistenceMedium方法是将viewstate的内容发到客户端浏览器中,那么每次向服务器发请求,都需将体积庞大的viewstate字段发回服务器,服务器返回结果时,又将体积庞大的viewstate字段发回来。这给应用程序整体性能带来了很大冲击。BasePage类改写了此两个方法。将viewstate内容放到session中,用的时候又从session取回来。这样避免了在网络上来回传输体积庞大的viewstate内容。 

应用程序的所有页面都继承此BasePage类。这样就可以将此方法应用于所有的asp.net web form页面。

其效果如下:

 
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
 
</title>
</head>
<body>
    <form method="post" action="Default.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="" />
</div>
 
<script type="text/javascript"> 
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
    theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
//]]>
</script>
 
 
    <div>
        
    <span id="ContentPlaceHolder1_Label1">My label</span>
<div>
	<table cellspacing="0" rules="all" border="1" id="ContentPlaceHolder1_grdAddress" style="border-collapse:collapse;">
		<tr>
			<th scope="col">AddressID</th><th scope="col">AddressLine1</th><th scope="col">AddressLine2</th><th scope="col">City</th><th scope="col">StateProvince</th><th scope="col">CountryRegion</th><th scope="col">PostalCode</th>
		</tr><tr>
			<td>9</td><td>8713 Yosemite Ct.</td><td> </td><td>Bothell</td><td>Washington</td><td>United States</td><td>98011</td>
		</tr><tr>
			<td>11</td><td>1318 Lasalle Street</td><td> </td><td>Bothell</td><td>Washington</td><td>United States</td><td>98011</td>
		</tr><tr>
			<td>25</td><td>9178 Jumping St.</td><td> </td><td>Dallas</td><td>Texas</td><td>United States</td><td>75201</td>
		</tr><tr>
			<td>28</td><td>9228 Via Del Sol</td><td> </td><td>Phoenix</td><td>Arizona</td><td>United States</td><td>85004</td>
		</tr><tr>
			<td>32</td><td>26910 Indela Road</td><td> </td><td>Montreal</td><td>Quebec</td><td>Canada</td><td>H1Y 2H5</td>
		</tr><tr>
			<td colspan="7"><table>
				<tr>
					<td><span>1</span></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$2')">2</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$3')">3</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$4')">4</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$5')">5</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$6')">6</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$7')">7</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$8')">8</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$9')">9</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$10')">10</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$11')">...</a></td><td><a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$grdAddress','Page$Last')">>></a></td>
				</tr>
			</table></td>
		</tr>
	</table>
</div>
<br />
 
    </div>
    </form>
</body>
</html>

 可见viewstate字段的内容完全没有了。这样html源代码的整体体积就小了很多。这对应用程序的性能提高是很大好处的。曾经只有asp.net mvc才有的体积小页面,现在asp.net web form也可以做到了。同时asp.net web form还有开发效率相对较高,还可以利用viewstate带来的好处,有了这些综合考虑,大家应该会重拾对asp.net web form的信心,继续在asp.net web form的旅程。

 

 

目录
相关文章
|
JSON 人工智能 前端开发
用markdown语法制作一个好看的网址导航页面(markdown-web-nav)
这是一篇关于创建网址导航页面的工具分享文章。作者介绍了从手动编写HTML代码到开发可视化工具 *markdown-web-nav* 的历程,旨在简化网址管理与导航页面生成的过程。该工具支持新增、编辑和删除网址数据,通过导入/导出JSON文件、实时预览Markdown效果以及一键复制等功能,让用户轻松制作美观的网站导航页面。文章还提供了详细的操作步骤及常见问题解答,如还原数据、获取网站图标链接等,适合不同技术水平的用户使用。
678 28
|
12月前
|
移动开发 前端开发 JavaScript
H5 页面与 Web 页面的制作方法
H5页面制作利用HTML5、CSS3和JavaScript技术,结合H5编辑器或框架(如Adobe Dreamweaver、Ionic),注重移动设备兼容性与响应式布局。Web页面制作则基于传统HTML、CSS和JavaScript,借助文本编辑器或IDE完成开发。两者区别在于技术版本、交互性和浏览器支持:H5更互动、现代,但可能不兼容旧浏览器;Web页面更静态、兼容性广。根据需求选择:高交互选H5,广泛兼容选Web。
1662 6
|
前端开发
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
892 1
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
|
编解码 前端开发 JavaScript
使用 CSS 打印样式为 Web 页面设置专业的打印机效果
使用 CSS 打印样式为 Web 页面设置专业的打印机效果
491 2
|
存储
在 Web 中判断页面是不是刷新
【9月更文挑战第10天】在Web开发中,判断页面是否刷新有多种方法:1) 监听`popstate`事件,检测用户是否通过历史记录访问页面;2) 记录并比较页面加载时间戳,若相差极小,则可能为刷新;3) 利用本地存储设置特定值,若该值不存在或不符合预期,则页面可能被刷新。然而,这些方法并非绝对准确。
758 3
|
数据处理 开发者 UED
FastAPI 的模板引擎简直太神奇啦!这就是构建动态 Web 页面的终极秘籍,快来一探究竟!
【8月更文挑战第31天】FastAPI 是一款高性能异步 Web 框架,可通过集成模板引擎(如 Jinja2 或 Mako)实现动态页面渲染。使用模板引擎可分离页面结构与数据,简化代码并提升可维护性。此外,它还提供丰富的语法支持,如循环和条件判断,从而增强页面展示效果及开发效率。通过简单的配置步骤,即可在 FastAPI 中启用模板引擎,显著改善用户体验。
1624 2
|
XML JavaScript 测试技术
Web自动化测试框架(基础篇)--HTML页面元素和DOM对象
本文为Web自动化测试入门指南,介绍了HTML页面元素和DOM对象的基础知识,以及如何使用Python中的Selenium WebDriver进行元素定位、操作和等待机制,旨在帮助初学者理解Web自动化测试中的关键概念和操作技巧。
280 1
html,web页面朗读文字,朗读中文,朗读英文
html,web页面朗读文字,朗读中文,朗读英文
|
数据处理 Python
Django视图:构建动态Web页面的核心技术
Django视图:构建动态Web页面的核心技术
【Azure 应用服务】Web.config中设置域名访问限制,IP地址限制访问特定的页面资源 (Rewrite)
【Azure 应用服务】Web.config中设置域名访问限制,IP地址限制访问特定的页面资源 (Rewrite)
279 0