ntwo

导航

ASP.NET站点性能提升-优化表单

客户端验证

ASP.NET验证控件

验证控件不只提供客户端的验证,也提供服务器端验证。如果页面上的任何一个验证控件验证不通过,page对象的IsValid属性值为false。

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。

<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)
{
  ...
}

页面方法可以访问请求上下文,例如:

string userAgent = HttpContext.Current.Request.UserAgent;

从JavaScript中调用

PageMethods.SaveForm(title, author, price, onSuccess, onError);
…
function onSuccess(result) {
…
}
function onError(result) {
…
}

result参数包含web方法返回值。

Web service

[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

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

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的攻击请求:

<img src="http://bank.com?withdraw=1000;sendto=evil" />

访问者的浏览器会发送一个到bank.com的请求。这个请求会包含说明访问者已经登录的cookie。所以,evil.com发送了一个代表访问者的请求。

为了阻止这个攻击,可以禁止GET请求。evil.com可以在它的页面上放置一个发送POST请求的表单解决这个问题。然后,它可以使用JavaScript代码提交表单,或诱骗访问者提交表单。一个防卫这种攻击的方法是只允许不是由表单使用的内容类型,例如application/json; charset=utf-8。

调用generic handler

为了将开销将到最小,不使用代理,使用jQuery的方法。

  1. 加载jQuery库。
  2. 加载JSON插件。可以在http://code.google.com/p/jquery-json/找到这个插件。
  3. 创建表单数据的JSON对象:
    var formdata = { 
        'title': ..., 
        'author': ...,
        'price': ...
    };
  4. 最后,在异步请求中向generic handler发送JSON对象:
    $.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:

About WCF Data Services:

posted on 2011-01-16 17:06  9527  阅读(531)  评论(0编辑  收藏  举报