ASP.NET站点性能提升-优化表单
客户端验证
ASP.NET验证控件
验证控件不只提供客户端的验证,也提供服务器端验证。如果页面上的任何一个验证控件验证不通过,page对象的IsValid属性值为false。
1 2 3 4 5 6 7 8 9 | protected void btnSave_Click( object sender, EventArgs e) { if (!Page.IsValid) { return ; } //Process Page ... } |
开销
使用ASP.NET验证控件会使ASP.NET在.aspx页面上加载很多内联JavaScript代码,大概有5KB或压缩后1KB。
它也会使ASP.NET从服务器下载JavaScript文件,一共41KB(压缩后11KB)。但是,如果这些文件在浏览器被缓存,在第二次访问时,就不会再加载了。
使用jquery validator
略
异步提交表单
异步提交表单方式比较
Method | Overhead | Description |
Classic ASP.NET | Very High | Very easy to use. Causes full-page refresh, requiring ViewState to maintain state of each control. |
UpdatePanel control | High | Very easy and quick to use. No need to write JavaScript. |
Page Methods | High | Lets you call C#/VB code behind methods with a single line of JavaScript. |
Web Service | Medium | Lets you call web services with a single line of JavaScript. |
Generic Handler | Low | The JavaScript to call an ASP.NET Generic Handlers is a bit more involved. Provices most scope for performance improvements. |
WCF Data Services and the Entity Framework | Medium | Allows you to generate the server-side data access code using Visual Studio. |
UpdatePanel控件
使用UpdatePanel控件,ScriptManager控件会向页面加入内联JavaScript,并加载JavaScript库(大约90KB)。
页面方法
首先在页面顶端加入ScriptManager控件。这会在页面上生成调用后端方法的JavaScript代理对象。ScriptManager控件需要设置EnablePageMethods属性为true。
1 2 3 4 5 6 7 8 9 10 11 | <body> <form id= "form1" runat= "server" > <asp:ScriptManager ID= "ScriptManager1" runat= "server" EnablePageMethods= "True" /> [System.Web.Services.WebMethod] public static string SaveForm( string title, string author, string price) { ... } |
页面方法可以访问请求上下文,例如:
1 | string userAgent = HttpContext.Current.Request.UserAgent; |
从JavaScript中调用
1 2 3 4 5 6 7 8 | PageMethods.SaveForm(title, author, price, onSuccess, onError); … function onSuccess(result) { … } function onError(result) { … } |
result参数包含web方法返回值。
Web service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | [WebMethod] public string SaveForm( string title, string author, string price) { ... } <body> <form id= "form1" runat= "server" > <asp:ScriptManager ID= "ScriptManager1" runat= "server" > <Services> <asp:ServiceReference Path= "FormService.asmx" /> </Services> </asp:ScriptManager> FormService.SaveForm(title, author, price, onSuccess, onError, onTimeout); ... function onSuccess(result) { } function onError(result) { } function onTimeout(result) { } |
Generic handler
Generic handler开销很小,并且允许异步访问数据库,这样可以更好地利用IIS工作线程。如果性能要优于易用性,generic handler是最好的选择。不像web services,generic handlers只暴露一个接口。
创建generic handler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public void ProcessRequest (HttpContext context) { if ((context.Request.HttpMethod != "POST" ) || // to prevent cross site request forgery attacks (context.Request.ContentType != "application/json; charset=utf-8" )) { context.Response.ContentType = "text/plain" ; context.Response.Write( "Access Denied" ); return ; } string json = RequestBody(context.Request); JavaScriptSerializer js = new JavaScriptSerializer(); FormData formData = js.Deserialize<FormData>(json); string message = Business.ProcessForm(formData.title, formData.author, formData.price); context.Response.ContentType = "text/plain" ; context.Response.Write(message); } |
FormData类:
1 2 3 4 5 6 | private class FormData { public string title = null ; public string author = null ; public string price = null ; } |
跨站请求伪造攻击
为什么不允许GET请求,并要求content type是application/json; charset=utf-8可以阻止跨站请求伪造(Cross Site Request Forgery(CSRF))攻击。
在CSRF攻击中,访问者被欺骗执行一小段HTML发送一个未意识的请求到访问者已经登录的站点。例如,假设一个访问者登录了bank.com。登录操作使用bank.com在访问者的计算机上放置了一个cookie,记住访问者已经登录了。然后如果访问者被诱惑访问evil.com页面,这个页面可能包含一个对bank.com的攻击请求:
1 |
访问者的浏览器会发送一个到bank.com的请求。这个请求会包含说明访问者已经登录的cookie。所以,evil.com发送了一个代表访问者的请求。
为了阻止这个攻击,可以禁止GET请求。evil.com可以在它的页面上放置一个发送POST请求的表单解决这个问题。然后,它可以使用JavaScript代码提交表单,或诱骗访问者提交表单。一个防卫这种攻击的方法是只允许不是由表单使用的内容类型,例如application/json; charset=utf-8。
调用generic handler
为了将开销将到最小,不使用代理,使用jQuery的方法。
- 加载jQuery库。
- 加载JSON插件。可以在http://code.google.com/p/jquery-json/找到这个插件。
- 创建表单数据的JSON对象:12345
var
formdata = {
'title'
: ...,
'author'
: ...,
'price'
: ...
};
- 最后,在异步请求中向generic handler发送JSON对象:1234567891011121314
$.ajax({
type:
"POST"
,
url:
"FormHandler.ashx"
,
data: $.toJSON(formdata),
contentType:
"application/json; charset=utf-8"
,
dataType:
"text/plain"
,
success: onSuccess,
error: onError
});
...
function onSuccess(result) {
}
function onError(result) {
}
如果希望发送请求而不传入任何数据,设置data为空对象”{}”。这样ajax方法在请求中不会设置content-length头,IIS会阻止这个请求。
WCF Data Services和Entity Framework
略
更多资源
Abount ADO.NET Entity Framework:
- The ADO.NET Entity Framework Overview:
http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx - Object-relational mapping
http://en.wikipedia.org/wiki/Object-relational_mapping
About WCF Data Services:
- WCF Data Services:
http://msdn.microsoft.com/en-us/library/cc668792.aspx - Open Data Protocol Documentation
http://www.odata.org/developers/protocols - Overview: ADO.NET Data Services
http://msdn.microsoft.com/en-us/library/cc956153.aspx - Using Microsoft ADO.NET Data Services
http://msdn.microsoft.com/en-us/library/cc907912.aspx - Interceptors (WCF Data Services)
http://msdn.microsoft.com/en-us/library/dd744842.aspx
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架