65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET 中使用 HTML 表单管理状态 - 轻量级替代方案

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.73/5 (11投票s)

2008年12月12日

CPOL

4分钟阅读

viewsIcon

31302

downloadIcon

140

一个灵活、轻量级的表单处理库,无需使用ViewState、postback或服务器端表单元素。

引言

为了实现 ASP.NET (而不是 ASP 或 PHP) 的全部优势,通常会使用传统的服务器控件 - ViewState - PostBack 模型,通过自动处理表单提交之间的应用程序状态维护来加快开发时间,并允许开发人员专注于功能,而不是将时间浪费在如在 postback 后重新填充表单字段和编写混乱的内联代码来完成这些事情上。

然而,当使用复杂的 CSS 和 JavaScript 开发界面密集型应用程序时,这种模型存在缺点,并且在尝试使用非 ASP.NET AJAX 的 AJAX 时会尤其成问题 - 问题在于,在使用服务器控件 (甚至设置了 runat=server 的 HTML 控件) 时,开发人员编写的前端代码通常与服务器上生成的代码几乎没有相似之处。 它还可能非常慢,尤其是在引入 ASP.NET AJAX 时。

这里的库提供了一种替代方案,允许使用纯 HTML 和/或 JavaScript,使用客户端表单来开发前端,同时保留从服务器端代码维护页面状态和操作页面内容的能力,而无需使用任何内联标签。 此外,有限的“跨页面 PostBack”支持问题也已解决 - 用户在表单处理完成后被发送到的目标页面无需与提交页面有任何关系。

目前,该库未经修改,具有以下功能,开箱即用

  • 在 POST 之间维护 INPUT (text, password, radio, checkbox, and hidden) 和 SELECT  标签的状态,以及/或允许从服务器端代码设置它们的状态。
  • 允许将普通的客户端容器元素 (例如 DIVs, SPANs) 用作标签和/或面板,并从服务器端设置其内容。 
  • 允许开发人员指定在表单处理完成后在目标页面上运行的任意 JavaScript。

使用库

该库包含一个用户控件 FakePostBack.ascx,用于放置在您希望使用该库的 ASPX 页面中,以及 FormProcessor.cs 类,用于放置在您的 app_code 文件夹中。

我捆绑了一个示例“计算器”应用程序来演示用法… 让我们一起看这个例子。

前端代码 (Demo.aspx)

<%@ Register Src = "FakePostBack.ascx" TagName="FormHelper" TagPrefix="sam" %>
<html>
<head>
</head>
<body onload="FormHelper.Populate();">
<sam:FormHelper runat="server" id="customForm"></sam:FormHelper>
    <form name="calculate" method="post" action="Calculator.aspx">
        <h2>Demo App using Form Processor.NET</h2>
        <b>Enter an integer:</b><br />
        <input type="text" id="num1" name="num1" /><br /><br />
        <b>Enter another integer:</b><br />
        <input type="text" id="num2" name="num2" /><br />
        <input type="submit" value="Calculate Sum" />
    </form>
    
    <div id="sum"></div>
    
    <script>
    function SayHello()
    {
        alert("Thanks for using the calculator.");
    }
    </script>
</body>
</html>	

这是一个绝对标准的 HTML 页面。包含库前端部分所做的所有工作是添加 FakePostBack.ascx 控件,并将其放置在相关的表单上方。该控件除了 runat=server 之外不需要任何属性。此外,<body> 标签已修改为在加载时运行 FormHelper.Populate - 这初始化了控件。

上述 Demo.aspx 页面的代码隐藏是空的 - 不需要。

表单处理代码 (Calculator.aspx.cs)

这是一个纯服务器端页面 (Calculator.aspx 是空的),其工作是使用我们的 FormProcessor 类处理来自 Demo.aspx 的提交表单。

让我们看看这里发生了什么

FormProcessor p = new FormProcessor("Demo.aspx");

//Retrieve the posted fields and do all necessary processing
int a = Int32.Parse(p.Get("num1", "text"));
int b = Int32.Parse(p.Get("num2", "text"));
int c = a+b;

//Specify the text to display on return, and the container to hold it
p.SetLabel("sum", "The sum is: "+c.ToString());

//Add JavaScript, just for fun
p.AddScript("SayHello();");

p.Finish();

创建一个 FormProcessor 实例,指定处理完成后要加载的页面 - 在本例中是提交页面 - 但它可以是任何包含客户端控件的页面。 

简单看一下一些相关的行,它们将向您展示如何使用该库

p.Get("num1", "text") 

这会返回“num1”输入字段的内容 - 它等同于使用 Request.Form["num1"] ,但同时维护状态。Get 方法的第二个参数指定了表单字段的类型 (可用值包括“text”、“select”、“radio”、“checkbox”) - “text”也包括隐藏字段和密码字段。

p.SetLabel("sum", "The sum is: "+c.ToString());

这指示客户端模块用指定的内容填充空的 <div id="sum">

p.AddScript("SayHello();"); 

这里指定的 JavaScript 将在目标页面上执行。

p.Finish() 

浏览器被重定向到 Demo.aspx,即 FormProcessor 构造函数中指定的 URL。

提交前页面

before.JPG

提交后页面

after.JPG

工作原理

我不会深入细节 - FormProcessor.csFakePostBack.ascxFacePostBack.ascx.cs 中的代码很容易理解,但简而言之

FormProcessor.csGet()SetLabel()AddScript() 方法会添加到 JSON 数组中。 FormProcessor.Finish() 将此数组放入 Session 变量,然后重定向到包含 FakePostBack.ascx 的页面。

FakePostBack.ascx 的代码隐藏会检查 Session 变量是否存在;如果存在,它会被放入一个 public string ,然后被销毁。

最后,调用 FormHelper.Populate() 会调用由 FakePostBack.ascx 生成的 JavaScript - 它从代码隐藏中获取包含 JSON 的 string ,如果 string 不为空,则遍历数组,填充表单字段,设置元素的内容,并执行任何脚本块。

致谢

Sanford Liu,Supernova Interactive 的杰出产品经理,给了我使用 JSON 作为表单提交后跟踪验证错误并显示它们 (如果发生错误) 的方法的想法。

然后,昨晚,大约凌晨 1 点,在送一位美丽的女士去火车站后,我意识到我可以用这个概念来构建一个可行的 ASP.NET 服务器端表单的替代方案。我做到了。 :)

尽情享用!

历史

  • 2008 年 12 月 12 日:首次发布
© . All rights reserved.