- 浏览: 154041 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
liveandevil:
我的一直出现驱动找不到的错误 你那个驱动jar文件时放在哪里 ...
JDBC数据库通用DAO -
zouc816:
hi,wjm901215
我看你这篇文章对mapXtreme ...
用mapXtreme Java开发web gis应用 (下)
Dino Esposito
Form(表单)是ASP.NET开发中重要的组成部分--没有Form就没有ASP.NET Web编程模型。Form不局限于纯粹的HTML,但是在ASP.NET中会受到一些限制。对于ASP.NET页面,Form可以提交自身,并且ASP.NET模型提供了控件状态管理和postback事件。由于ASP.NET的单一Form模型使得编写ASP.NET应用程序简单又便捷.
ASP.NET中窗体上的限制可能听起来怪异而武断,但实际上跟ASP.NET模型有直接的作用。然而,有一种实际情况是ASP.NET 1.x form 模型所不支持的:在同一个页面拥有多个,互不干涉的form。比如,您不能在某个页面上添加一个搜索文本框并将结果提交到另一个页面.
在msdn杂志2003年5月刊上,我写了一个专栏关于ASP.NET 1.x的Form编程(参阅 Cutting Edge: Form-based Programming in ASP.NET),对于ASP.NET 2.0的介绍里, 关于提交给不同的页面这一主题的地址有一些变动。本文我将讨论ASP.NET 2.0下的Form编程.
窗体呈现
让我们探索一下ASP.NET的窗体世界,去了解窗体(包括控件)是如何实际呈现的。在ASP.NET页面上,<form>标记可以是几种容器控件像<table>, <div>, 或 <body>的子控件; 然而,在大多数页面中,<form>只是简单作为<body>的子节点。如果一个非容器控件(比如TextBox)被放置在form标记之外,将会抛出一个运行时错误(编译时不会对此进行检查)。请看如下代码,节选自TextBox的 AddAttributesToRender 方法:
protected override void AddAttributesToRender(HtmlTextWriter writer) { if (this.Page != null) this.Page.VerifyRenderingInServerForm(this); ... } |
调用页面的VerifyRenderingInServerForm方法将会处理此工作。(当您自己编写自定义服务器控件时应避免这种行为)
HtmlForm类
HtmlForm继承自HtmlContainerControl,使得窗体具有包含子控件的能力。HtmlForm提供了对HTML<form>元素在服务器端的编程访问能力,其properties列表见图1。从表中可以看到ASP.NET 1.x 和 ASP.NET 2.0的变化主要限于几个properties。
一个表单必须拥有唯一的名字,未指定名字时ASP.NET会自动分配一个。可以通过ID或Name属性给Form设置标识,同时设置时以ID属性优先。可是有一点要注意,一些编程接口使用Name属性来兼容xhtml。在xhtml中,elements通过ID标识而不是Name,因此通常来讲,最好以ID属性为准。
表单的父对象是一个具有runat属性的总容器控件。如果这样的控件不存在,页面对象被作为父对象。典型的服务器端form的容器是标记为服务器端对象的<table>或<div>。
图2 列出了HtmlForm类中最常用的到一些方法。这些方法继承于System.Web.UI.Control类。注意FindControl方法只搜索form的直接子控件。内部容器中的子控件和表单子控件的子控件将不能被找到。
多表单管理
通常来讲,投入单表单模型的怀抱而放弃对多表单系统的支持并不算是很大的牺牲。尽管一些页面如果能使用multiple forms将会获得更加致一致和自然的设计--至少对于那些包含有一定逻辑关系的输入控件组的表单 例如,一个页面除了要给用户提供信息,还需要支持一个搜索表单或者登录框表单。
您可以将搜索和登录功能合并到ad hoc类并通过显示信息的同一页面调用,然而这并不是构造代码的最佳方法。
如果您正在将老的代码移植到ASP.NET, 您可能觉得将登录和搜索代码置于另一个专门的页面更容易些。可是您如何才能将那些页面的数据提交到本页呢?
在单表单模型里,页面总是提交自身而且也没有给开发者提供设置回传目标的钩子。对于HTML和ASP编程,表单的Action属性是单一值,在ASP.NET的HtmlForm类中也不暴露此属性。单表单模型跟ASP.NET平台整合的太紧密,您要么采用要么放弃——或者,做为一个附加的选择就是可以用ASP的方式编写代码不使用服务器表单。象下面要讲到的,在ASP.NET 2.0里,可以将数据提交到另一个页面,但是这个特性是通过一些按钮控件的新增功能得以实现的。现在,我们先看看使用HTML的非服务器端表单时有什么棘手问题。
在ASP.NET中,当有多个HtmlForm控件需要呈现时将会抛出异常。页面中的第一个HtmlForm控件被呈现后,会有一个布尔标记被设为true,此标记指示了是否有HtmlForm已被呈现,当另一个HtmlForm试图呈现时,由于此标记已经被设置为true因而引发一个异常。
如果一个Web Form中包含了一个服务器form和任意数量的不含有runat属性的<form>标记不会导致任何错误。没有runat属性,任何标记都成为纯粹单一的HTML而直接呈现(见图3).
此页面包含2个表单,第二个是没有ruan="server"属性的HTML表单,因此被ASP.NET完全忽略。提供给浏览器的html中合法包含了两个<form>元素,它们指向两个不同的action URL。
然而从功能上来讲此代码有一个大的缺陷:不能使用ASP.NET编程模型来检索客户端表单action页面上的提交数据。当编写search.aspx时,对于客户端表单的action页面,不能对页面的控件借助视图状态和提交数据来读取和更新它们的状态。(The apparent statefulness of ASP.NET server controls is obtained by making pages post to themselves)为了知道提交给search.aspx的数据,您必须采取针对ASP模型的直接在回传数据中检索的传统风格:
protected void Page_Load(object sender, EventArgs e) { // Use the Request to retrieve posted data string textToSearch = Request.Form["Keyword"].ToString(); ... // Use standard ASP.NET to populate the page UI KeywordBeingUsed.Text = textToSearch; } |
可以使用 HttpRequest 对象协议规范中的集合(Page.Request等同于HttpContext.Current.Request)来检索回传的数据——对于POST方式时使用Form,GET方式时使用QueryString,或者想要兼容对Form、QueryString、 ServerVariables 和 Cookies的访问时使用Params。HttpRequest 对象会在页面创建前将数据封装,因此,页面的任何事件都可以随意调用Page.Request.对于自提交的ASP.NET页面,不需要使用Request是由于可以借助于一个强类型的编程模型,但是对于以前,可靠的 HttpRequest 对象依然是需要时为您而备的。
还有一件有趣的事要注意,当用户点击Search按钮时,search.aspx被调用,它只接受那些Html 表单上发送回来的数据,不会有视图状态被回传,也没有额外的数据传递。如果必须提交数据到另一个页面,使用传统风格仍然是多数高效性能的明智之选。如随后本专栏所述,ASP.NET 2.0 跨页提交特性传递了相当大的,类视图状态的数据域。
多 <form> 标记
如果多个服务器端form出现在同一个web form上,将抛出异常。不易发现并不为人知的是,事实上web form可以包含任意数量的服务器端form,只要同一时刻仅有一个可见并呈现。例如,一个页面包含有3个带有runat="server"标记的<form>是允许的,但是仅有一个form的Visible属性可以设置为true.通过激活HtmlForm类的Visible属性,您可以在页面的生命周期改变活动的服务器端form。这个小窍门不能解决同时有多个活动form的问题,但是有时还是有所帮助的。
让我们考虑一下图4中的页面,所有的<form>被标记为runat="server",但是只有第一个是可见的,互斥的form在ASP.NET 1.x中很顺利的实现了一个向导。通过在按钮事件中转换各form的可见性,您可以获得一个类向导的行为,参看图5:
图5 类向导页面的运行效果
这个技巧在ASP.NET 2.0中基本没用,因为您会发现有2个新控件:MultiView 和 Wizard。MultiView控件使用逻辑等同的互斥表单,可惜它使用panel而没用正统的form。MultiView允许你定义多个互斥的HTML panel,并提供了API来切换这几个panel的可见性,并确保同一时刻只有一个被激活并可见。MultiView控件没有提供内建的用户接口。Wizard控件仅是MultiView加上一个类向导的预定义的UI块,我在MSDN杂志2004年11期上讲解过它(参阅 Cutting Edge: The ASP.NET 2.0 Wizard Control )。
Cross-Page Posting(跨页提交)
ASP.NET 2.0 提供了一个新的内建进制以覆盖常规处理周期并允许页面提交到另一个页面。通常,postback发生在下面两种方式之一:Submit按钮激发或通过script激发。典型的按钮提交自动指向form指定的提交地址,而如果提交是通过script时则更加灵活机动。在ASP.NET 2.0中,您可以配置某个控件(尤其那些实现了新的IButtonControl接口的)使其可以提交给其他目标页面,具体可以查阅cross-page posting。
实现IButtonControl的核心控件是Button, ImageButton, 和 LinkButton。通常,通过实现IButtonControl,所有的自定义控件都可以有表单中的按钮同样的效果。IButtonControl接口正是一个ASP.NET从1.0到2.0迁移时代码重构的一个典型例子。IButtonControl接口聚合了ASP.NET 1.x支持的多数按钮控件(包括一些html按钮控件)的一些属性。另外,一些新的属性公布了新增的功能,象PostBackUrl 和 ValidationGroup,图6详细描述了IButtonControl接口。接下来的代码片断演示了如何使用:
<form runat="server"> <ASP:textbox runat="server" id="Data" /> <ASP:button runat="server" id="buttonPost" Text="Click" PostBackUrl="target.aspx" /> </form> |
当PostBackUrl属性被设置,ASP.NET运行时为按钮控件的相应的html元素绑定一个新的JavaScript功能。将会使用新的WebForm_DoPostBackWithOptions函数取代常规我们使用的__doPostback函数,客户端呈现效果如下:
<input type="submit" name="buttonPost" id="buttonPost" value="Click" onclick="BLOCKED SCRIPTWebForm_DoPostBackWithOptions( new WebForm_PostBackOptions("buttonPost", "", false, "", "target.aspx", false, false))" /> |
结果是,当用户点击按钮时,当前的表单提交内容给指定的目标页。那么视图状态的情况呢?当含有可以cross-page posting的控件时,页面会创建一个name为__PREVIOUSPAGE的隐藏域,此域包含了提交页的信息。目标页使用此信息来创建一个完整状态的引用来调用页对象。
在目标页,您可以使用Page类的新增的一个属性PreviousPage来引用提交页和页面上所有的控件。下面是目标页面对form中某TextBox内容检索的后台代码:
protected void Page_Load(object sender, EventArgs e) { // Retrieves some posted data TextBox txt = (TextBox) PreviousPage.FindControl("TextBox1"); ... } |
通过使用Page类的PreviousPage属性,可以访问提交页上声明的任意输入控件.对输入控件的访问是弱类型的并间接使用FindControl方法.摆在事实面前的问题是目标页面并不知道关于提交页类型的任何信息.同样地,它也不能提供对源页面类的指定成员的访问.
此外,注意FindControl仅仅查找当前container中的控件,如果你要找的控件是在另一个控件内部(比如模板),您必须首先取得这个container的引用然后再搜索container来查找那个控件.为了避免完全借助FindControl,还需要另一种途径.
为了检索提交页面上的的值,FindControl将仅提供安全的选项当您预先不知道将会调用哪个目标页时.然而,当在应用程序的上下文中使用cross-page posting时,将有机会确切知道的是谁将调用和如何调用这个页面.这种情况下,您可以利用PreviousPageType指令使目标页的PreviousPageType属性强类型为源页面类.在目标页,添加下面的指令:
指令可以为两个互斥属性之一:VirtualPath 或 TypeName.VirtualPath指提交页的URL,TypeName则指明调用页的类型.PreviousPageType指令使目标页PreviousPage属性返回给定路径上的页面相同类型(或者TypeName属性指定的类型)的一个对象引用,而事实本身是您不能直接访问输入控件.在ASP.NET中,每个页面类包含了子控件对应的protected成员.不幸的是,您不能调用外部类的受保护成员.事实上,只有派生类可以访问父类的受保护成员.
为了达到这个目的,您必须在调用页上在一个public属性来进行提交页信息的访问.例如,假象crosspostpage.aspx页上包含一个名字为_textBox1的TextBox,为了使它能够在目标页访问,必须在后台类增加如下代码:
public TextBox TextBox1 { get { return _textBox1; } } |
作为cross-page调用潜在可能的目标,不会自动将目标页成为别的类型.通常目标页总是被自身调用,例如通过一个超链接.这种情况发生时PreviousPage属性返回null并且别的回传相关的属性(象IsPostBack)采用常规值.对于双重功能的页面,好的办法是添加额外的代码来分辨页面的行为.下面的Page_Load事件中的代码使页面只工作于cross-page调用方式:
if (PreviousPage == null) { Response.Write("Sorry, that's not the right way to invoke me."); Response.End(); return; } |
页面重定向
除了按钮控件的PostBackUrl属性,ASP.NET提供了另一个页面间传递控件和值的机制:Server.Transfer方法.当你调用此方法,新页面的URL不会反映到浏览器的地址栏,因为这种页面转向发生服务器端--在客户端不会有任何间接事件发生.下面的代码演示了如何使用此方法来进行页面定向:
protected void Button1_Click(object sender, EventArgs e) { Server.Transfer("targetpage.aspx"); } |
注意下面对页面中进行重定向的调用代码不会被执行.最后,Transfer只是页转向的方法.可是,却对两种情况十分有效:第一,客户端的请求.例如,使用Response.Redirect.第二,同一个应用程序中某请求要在新的页面请求被重用.
对于ASP.NET 1.x,可以通过使用http上下文的Handler属性获取调用对象,象下面所示:
Page caller = (Page) Context.Handler;
由于Handler属性返回了一个有效的对象引用,主体页可以访问它的public成员,但是象我们上面讨论过的不能直接访问页面上受保护级别的控件.
本编程模型也使用于ASP.NET 2.0, 不过,在 ASP.NET 2.0中,变得更简单了,不再需要使用Handler.你可以使用与cross-page postings相同的编程模型并借助一个非空的PreviousPage属性和强类型访问输入域的@PreviousPageType指令来处理.那么页面如何才能检测它是被server transfer调用还是cross-page postback?两种方式下PreviousPage都是非空的,但是PreviousPage对象的Page.IsCrossPagePostBack在cross-page posting方式是为true,而erver transfer则为false.
小结
从一个页面传值到另一个页面有很多种方法可以达成--cross-page posting,server transfer,HTML forms, cookies, session-state, query strings, 或者其他方法等等.那么最有效的是哪个呢?在 ASP.NET 2.0中,cross-page posting 和 server transfer提供了一个常见的编程模型,但却潜在地通过View State移动了大块的数据。而这些信息是否真正需要依赖于目标页面的描述。在很多情况下,目标页面仅仅需要接收启动运作的一些参数。if this is so,HTML客户端表单可能用移动数据更加有效,尽管HTML表单需要一个类ASP的编程模型。
ASP.NET 2.0为HtmlForm类增加了一些新的特性,然而核心行为并未改变,因此提交自身仍是ASP.NET编程的主要方法。您可以混合客户端form和服务器form,也可以拥有多个服务器form不过同一时间内仅有一个可见。
问题和评论请发送至 cutting@microsoft.com.作者简介
Dino Esposito在意大利罗马工作,任职讲师兼顾问。《Programming ASP.NET》和新书《Introducing ASP.NET 2.0》(两书均由Microsoft Press出版)的作者,他将大部分时间用于讲授ASP.NET和ADO.NET方面的课程以及在各种会议上演讲。如果希望与Dino取得联系,请发送email至 cutting@microsoft.com 或者浏览他的blog站点:http://weblogs.ASP.NET/despos。
译自 MSDN Magazine 2005年9月刊 .
图 1 Properties of the HtmlForm Class
Attributes | Inherited from Control. Gets a name/value collection with all the attributes declared on the tag. | ||
ClientID | Inherited from Control. Gets the value of UniqueID. | ||
Controls | Inherited from Control. Gets a collection object that represents the child controls of the form. | ||
DefaultButton | String property. Gets or sets the button control to display as the default button on the form. | ||
DefaultFocus | String property. Gets or sets the button control to give input focus when the form is displayed. | ||
Disabled | Gets or sets a value indicating whether the form is disabled. Matches the disabled HTML attribute. | ||
EncType | Gets or sets the encoding type. Matches the enctype HTML attribute. | ||
ID | Inherited from Control. Gets or sets the programmatic identifier of the form. | ||
InnerHtml | Inherited from HtmlContainerControl. Gets or sets the markup content found between the opening and closing tags of the form. | ||
InnerText | Inherited from HtmlContainerControl. Gets or sets the text between the opening and closing tags of the form. | ||
Method | Gets or sets a value that indicates how a browser posts form data to the server. The default value is POST. Can be set to GET if needed. | ||
Name | Gets the value of UniqueID. | ||
Style | Gets a collection of all cascading style sheet (CSS) properties applied to the form. | ||
SubmitDisabledControls | Indicates whether to force controls disabled on the client to submit their values, allowing them to preserve their values after the page posts back to the server. False by default. | ||
TagName | Returns "form". | ||
Target | Gets or sets the name of the frame or window to render the HTML generated for the page. | ||
UniqueID | Inherited from Control. Gets the unique, fully qualified name of the form. | ||
Visible | Gets or sets a value that indicates whether the form is rendered. If false, the form is not rendered to HTML. |
图 2 Methods of the HtmlForm Class
ApplyStyleSheetSkin | Applies the skin in the defined page theme in the manner defined by StyleSheetTheme. | ||
DataBind | Calls the DataBind method on all child controls. | ||
FindControl | Retrieves and returns the control that matches the specified ID. | ||
Focus | Sets the input focus to a control. | ||
HasControls | Indicates whether the form contains any child controls. | ||
RenderControl | Outputs the HTML code for the form. If tracing is enabled, caches tracing information to be rendered later, at the end of the page. |
图 3 Server and Client Forms in the Same Page
<html> <body> <table><tr><td> <form id="form1" runat="server"> <h2>Ordinary contents for an ASP.NET page</h2> </form> </td> <td> <form method="post" action="search.aspx"> <table><tr> <td>Keyword</td> <td><input type="text" id="Keyword" name="Keyword" /></td> </tr><tr> <td><input type="submit" id="Go" value="Search" /></td> </tr></table> </form> </td> </tr></table> </body> </html> |
图 4 Markup for an ASP.NET 1.x Wizard-Like Page
<html> <body> <form id="step0" runat="server" visible="true"> <h1>Welcome</h1> <asp:textbox runat="server" id="Textbox1" /> <asp:button ID="Button1" runat="server" text="Step #1" OnClick="Button1_Click" /> </form> <form id="step1" runat="server" visible="false"> <h1>Step #1</h1> <asp:textbox runat="server" id="Textbox2" /> <asp:button ID="Button2" runat="server" text="Previous step" OnClick="Button2_Click" /> <asp:button ID="Button3" runat="server" text="Step #2" OnClick="Button3_Click" /> </form> <form id="step2" runat="server" visible="false"> <h1>Finalizing</h1> <asp:button ID="Button4" runat="server" text="Finish" OnClick="Button4_Click" /> </form> </body> </html> |
图 6 IButtonControl Interface
CausesValidation | Boolean value indicating whether validation is performed when the control is clicked. |
CommandArgument | Gets or sets an optional parameter passed to the button's Command event along with the associated CommandName. |
CommandName | Gets or sets the command name associated with the button that is passed to the Command event. |
PostBackUrl | Indicates the URL that will handle the postback triggered through the button control. |
Text | Gets or sets the caption of the button. |
ValidationGroup | Gets or sets the name of the validation group to which the button belongs. |
Visible | Boolean value indicating whether the button control is rendered. |
相关推荐
ASP.NET表单验证是开发Web应用程序时不可或缺的一部分,它确保用户输入的数据符合预期的格式和标准,从而提高数据质量和安全性。在ASP.NET框架中,表单验证提供了多种方法来检查和处理用户输入,以防止无效数据进入...
1. **Asp.net表单控件**:Asp.net提供了一系列内置的表单控件,如TextBox、DropDownList、RadioButton、CheckBox等,用于构建用户输入界面。在设计注册表单时,我们需要根据需求合理选择和组合这些控件,确保用户...
这份"绝对周全的Asp.net表单提交验证方案"PDF提供了一个详尽的指南,包括了从基础到高级的各种验证技术。 首先,基础的表单验证通常涉及到客户端验证和服务器端验证。客户端验证主要利用JavaScript或者jQuery等前端...
在这个特定的场景中,我们关注的是ASP.NET中的表单验证以及如何结合使用第三方库artDialog来创建弹出对话框。 **表单验证**在ASP.NET中扮演着关键角色,确保用户输入的数据符合预设的业务规则。ASP.NET提供了一系列...
本文档详细介绍了ASP.NET安全机制,利用这个安全机制,可以最大程度的防止网站被非法侵入
action属性指明当前表单提交之后由哪个程序来处理,这个处理程序可以是任何动态网页或者servlet或者CGI(Common Gateway Interface),在asp.net里面一般都是都aspx页面来处理。 method属性指明form表单的提交方式。...
**ASP.NET表单提交** 在ASP.NET中,用户界面通常是基于Web表单(Form)构建的。当用户填写表单并点击提交按钮时,浏览器会将表单数据发送回服务器,这个过程就称为表单提交。表单提交有两种方式:GET和POST。GET方式...
ASP.NET MVC 是微软提供的一种基于模型-视图-控制器(Model-View-Controller)模式的Web应用程序开发框架。它允许开发者使用HTML、CSS和JavaScript构建动态、数据驱动的Web应用,同时提供了强大的测试支持和对现有...
**第9章:数据与ASP.NET表单** - 讨论了如何在ASP.NET表单中显示和操作数据。 - **数据绑定**:通过数据绑定机制,可以轻松地将数据库中的数据展示在Web表单上。 - **数据验证**:为了保证数据质量,必须实施有效的...
ASP.NET 可编辑输入自动匹配的下拉框 本文将详细介绍 ASP.NET 可编辑输入自动匹配的下拉框的实现方法,该控件可以自动匹配用户输入的内容,并提供相关的下拉选项。本文将从三个方面介绍该控件的实现方法:首先,...
ASP.NET是微软公司推出的一种基于.NET Framework的Web应用程序开发框架,它为开发者提供了一种高效、强大且易于使用的工具来构建动态网站、Web应用程序和服务。本教程“使用ASP.NET技术开发网上书店”将深入探讨如何...
ASP.NET 是微软公司开发的一种用于构建 Web 应用程序的框架,它允许开发者使用.NET Framework 或.NET Core 进行服务器端编程。在这个“asp.net 后台管理系统界面”中,我们主要关注的是如何利用 ASP.NET 来设计和...
3. **Web表单和控件**:ASP.NET Web表单允许开发者创建交互式网页,通过使用各种内置控件(如文本框、按钮、下拉列表等)来构建用户界面。 4. **ASP.NET MVC**:虽然题目没有明确指出,但有可能开发者采用了ASP.NET...
一套基于C#+ASP.NET实现的Web页面控件类库及页面表单设计程序代码。
【ASP.NET Web控件】ASP.NET提供了丰富的Web控件,如RequiredFieldValidator用于表单验证,CompareValidator用于比较输入数据。这些控件简化了客户端和服务器端验证,以及错误消息的呈现。控件的属性如 Visible 和 ...
在这个文档中,我们将深入探讨ASP.NET MVC中的表单处理,这对于理解和实践Web应用开发至关重要。 首先,了解表单在Web应用中的作用是基础。表单允许用户输入数据,并将其发送回服务器进行处理。在ASP.NET MVC中,...
在 ASP.NET 中,数据表单验证是确保用户输入符合特定业务规则的重要步骤,以防止无效数据进入系统。在这个程序例子中,我们将探讨如何使用 "image" 这一元素进行创新的错误信息显示。 传统的 ASP.NET 表单验证通常...
ASP.NET单文件带进度条上传解决方案 本文主要讲述了ASP.NET单文件带进度条上传的解决方案,通过使用jquery框架和ASP.NET缓存机制,实现了文件上传和进度条显示的功能。 知识点1:使用jquery框架实现文件上传 在...
虽然说学习ASP.NET不需要任何ASP基础,但是我觉得如果大家ASP不会,还是先看一下【十天学会ASP教程】,大家所需要了解的不是ASP的程序怎么写,而是怎么构建服务器,怎么使用HTML表单,同时对SQL语句有一个基础和理解...
总结来说,ASP.NET MVC3的表单提交和异步提交是构建Web应用程序不可或缺的元素。表单提交适合简单的交互,而Ajax提交则能提升用户体验,尤其是在需要频繁与服务器交互或更新局部页面时。理解并熟练运用这两种提交...