将 ValidationGroup 和客户端验证与 ASP.NET 自定义服务器控件结合使用
我正在创建一个自定义服务器控件,以便为我的 Web 窗体应用程序生成具有特定标记和 JavaScript 处理程序的按钮元素。当然,它们能够引起回发,因此我希望它们能够与任何 ASP 的表单验证控件(尤其是客户端框架)一起使用。
此按钮服务器控件支持 OnClientClick
属性,以便在带有提供的代码的按钮标记中发出 onclick
属性(主要用于用户单击删除按钮时的简单确认重新提示)对于列表视图或类似视图),因此使用 asp:Button
控件的方法将验证脚本作为 onclick 属性发出将是非常无效的。事实上,在标准 asp:Button
上同时指定 OnClientClick
和 ValidationGroup
属性结果非常糟糕。下面是一个非常明显的例子,说明了为什么它不能开箱即用:
页面标记
<asp:Button ID="btnSaveAsp" ValidationGroup="vgMyValidationGroup" OnClientClick="return true;" runat="server" />
渲染标记
<input type="submit" name="ctl00$cphBodyContent$lvMyList$ctrl0$btnSaveAsp" value="Save" id="cphBodyContent_lvUsers_btnSaveAsp_0"
onclick='return true; WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$cphBodyContent$lvMyList$ctrl0$btnSaveAsp", "", true, "vgMyValidationGroup", "", false, false))'>
这是现有的非工作代码,用于将控件与验证连接起来。除了发出类似的 onclick
属性之外,我找不到太多有关如何使用方法最好地完成此操作的文档。我认为我在重写的 AddAttributesToRender
方法中对 Page.ClientSCript.RegisterForEventValidation
的调用会连接客户端验证,但这似乎并不像我想象的那样起作用。如果需要,可以使用 jQuery 将附加处理绑定到按钮的单击事件:
自定义服务器按钮控件
<ToolboxData("<{0}:Button runat=server></{0}:Button>")> _
<ParseChildren(False)> _
<PersistChildren(True)> _
Public Class Button
Inherits System.Web.UI.WebControls.WebControl
Implements IPostBackDataHandler
Public Sub New()
MyBase.New(HtmlTextWriterTag.Button)
End Sub
<Category("Behavior")> _
<DefaultValue("")> _
Public Overridable Property PostBackUrl As String
Get
Return If(ViewState("PostBackUrl"), String.Empty)
End Get
Set(value As String)
ViewState("PostBackUrl") = value
End Set
End Property
<Category("Validation")> _
<DefaultValue(True)> _
Public Overridable Property CausesValidation As Boolean
Get
Return If(ViewState("CausesValidation"), True)
End Get
Set(value As Boolean)
ViewState("CausesValidation") = value
End Set
End Property
<Category("Validation")> _
<DefaultValue("")> _
Public Overridable Property ValidationGroup As String
Get
Return If(ViewState("ValidationGroup"), String.Empty)
End Get
Set(value As String)
ViewState("ValidationGroup") = value
End Set
End Property
<Category("Behavior")> _
<DefaultValue("")> _
<Description("Client-side script to be run when the button is clicked.")> _
Public Property OnClientClick As String
Get
Return If(ViewState("OnClientClick"), String.Empty)
End Get
Set(value As String)
ViewState("OnClientClick") = value
End Set
End Property
Protected Overrides Sub AddAttributesToRender(writer As HtmlTextWriter)
MyBase.AddAttributesToRender(writer)
If Not String.IsNullOrEmpty(OnClientClick) Then
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, OnClientClick)
End If
Dim postBackOptions = GetPostBackOptions()
If postBackOptions.TargetControl Is Me Then
writer.AddAttribute(HtmlTextWriterAttribute.Name, ClientID)
End If
If Page IsNot Nothing Then
Page.ClientScript.RegisterForEventValidation(postBackOptions)
End If
End Sub
Protected Overridable Function GetPostBackOptions() As PostBackOptions
Dim options As New PostBackOptions(Me) With {
.ClientSubmit = False
}
If Page IsNot Nothing Then
If CausesValidation AndAlso (Page.GetValidators(ValidationGroup).Count > 0) Then
options.PerformValidation = True
options.ValidationGroup = ValidationGroup
End If
If Not String.IsNullOrEmpty(PostBackUrl) Then
options.ActionUrl = HttpUtility.UrlPathEncode(ResolveClientUrl(PostBackUrl))
End If
End If
Return options
End Function
End Class
目前,此代码无法与 asp:CompareValidator
中的 asp:CompareValidator
一起使用相同的 ValidationGroup
来确定在发回服务器之前两个密码重置字段是否相等,并且在请求到达服务器端后也不会进行验证。
I am creating a custom server control to generate button elements with specific markup and JavaScript handlers for my Web Forms application. They are, of course, able to cause postbacks, so I would like them to function with any of ASP's validation controls for form validation, especially the client-side framework.
This button server control supports an OnClientClick
property to emit an onclick
attribute in the button tag with the code provided (primarily used for a simple confirmation reprompt when a user clicks a delete button for a list view or similar), so using the asp:Button
control's method of emitting the validation script as an onclick attribute will be pretty ineffectual. As a matter of fact, specifying both OnClientClick
and ValidationGroup
attributes on a standard asp:Button
turns out pretty badly. Here's a painfully obvious example of why that's not working out of the box:
Page Markup
<asp:Button ID="btnSaveAsp" ValidationGroup="vgMyValidationGroup" OnClientClick="return true;" runat="server" />
Rendered Markup
<input type="submit" name="ctl00$cphBodyContent$lvMyList$ctrl0$btnSaveAsp" value="Save" id="cphBodyContent_lvUsers_btnSaveAsp_0"
onclick='return true; WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$cphBodyContent$lvMyList$ctrl0$btnSaveAsp", "", true, "vgMyValidationGroup", "", false, false))'>
Here is the existing non-working code for wiring up the control with validation. I was unable to find much documentation on how best to accomplish this with a method aside from emitting a similar onclick
attribute. I thought my call to Page.ClientSCript.RegisterForEventValidation
in the overridden AddAttributesToRender
method would wire up the client-side validation, but that does not appear to be functioning as I assumed. If necessary, jQuery is available for use in binding additional handling to the button's click event:
Custom Server Button Control
<ToolboxData("<{0}:Button runat=server></{0}:Button>")> _
<ParseChildren(False)> _
<PersistChildren(True)> _
Public Class Button
Inherits System.Web.UI.WebControls.WebControl
Implements IPostBackDataHandler
Public Sub New()
MyBase.New(HtmlTextWriterTag.Button)
End Sub
<Category("Behavior")> _
<DefaultValue("")> _
Public Overridable Property PostBackUrl As String
Get
Return If(ViewState("PostBackUrl"), String.Empty)
End Get
Set(value As String)
ViewState("PostBackUrl") = value
End Set
End Property
<Category("Validation")> _
<DefaultValue(True)> _
Public Overridable Property CausesValidation As Boolean
Get
Return If(ViewState("CausesValidation"), True)
End Get
Set(value As Boolean)
ViewState("CausesValidation") = value
End Set
End Property
<Category("Validation")> _
<DefaultValue("")> _
Public Overridable Property ValidationGroup As String
Get
Return If(ViewState("ValidationGroup"), String.Empty)
End Get
Set(value As String)
ViewState("ValidationGroup") = value
End Set
End Property
<Category("Behavior")> _
<DefaultValue("")> _
<Description("Client-side script to be run when the button is clicked.")> _
Public Property OnClientClick As String
Get
Return If(ViewState("OnClientClick"), String.Empty)
End Get
Set(value As String)
ViewState("OnClientClick") = value
End Set
End Property
Protected Overrides Sub AddAttributesToRender(writer As HtmlTextWriter)
MyBase.AddAttributesToRender(writer)
If Not String.IsNullOrEmpty(OnClientClick) Then
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, OnClientClick)
End If
Dim postBackOptions = GetPostBackOptions()
If postBackOptions.TargetControl Is Me Then
writer.AddAttribute(HtmlTextWriterAttribute.Name, ClientID)
End If
If Page IsNot Nothing Then
Page.ClientScript.RegisterForEventValidation(postBackOptions)
End If
End Sub
Protected Overridable Function GetPostBackOptions() As PostBackOptions
Dim options As New PostBackOptions(Me) With {
.ClientSubmit = False
}
If Page IsNot Nothing Then
If CausesValidation AndAlso (Page.GetValidators(ValidationGroup).Count > 0) Then
options.PerformValidation = True
options.ValidationGroup = ValidationGroup
End If
If Not String.IsNullOrEmpty(PostBackUrl) Then
options.ActionUrl = HttpUtility.UrlPathEncode(ResolveClientUrl(PostBackUrl))
End If
End If
Return options
End Function
End Class
Presently, this code does not function with an asp:CompareValidator
in the same ValidationGroup
to determine if two password reset fields are equal before posting back to the server, nor does validation occur once the request gets to the server side.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使
OnClientClick
与客户端表单验证一起使用由于
控件连接OnClientClick
的值> 使用表单验证脚本,让它们协同工作的最简单方法是,当您想要阻止表单提交时,返回 false
,如果您希望按钮验证并提交表单,则不执行任何操作:但是,如果你绝对想写
返回confirm('Are you certain?')
,然后您可以将表单验证代码移动到事件侦听器(按照您的建议),或者您可以包装OnClientClick
代码像这样:服务器端表单验证
您需要实现
IPostBackEventHandler
接口并调用Page.Validate
方法。ClientScriptManager.RegisterForEventValidation
方法用于事件验证(防止未经授权或恶意回发),而不是用于表单验证。示例代码 (C#)
以下是支持
OnClientClick
和ValidationGroup
的基本自定义按钮控件的代码:Making
OnClientClick
work with client-side form validationSince the
<asp:Button>
control concatenates the value ofOnClientClick
with the form validation script, the easiest way to make them work together is toreturn false
when you want to block the form submission, and do nothing if you want the button to validate and submit the form:However, if you absolutely want to write
return confirm('Are you sure?')
, then you can move the form validation code to an event listener (as you suggest), or you can wrap theOnClientClick
code like this:Server-side form validation
You need to implement the
IPostBackEventHandler
interface and call thePage.Validate
method. TheClientScriptManager.RegisterForEventValidation
method is used for event validation (preventing unauthorized or malicious postbacks), not for form validation.Sample code (C#)
Here is the code for a bare-bones custom button control that supports
OnClientClick
andValidationGroup
:请查看.NET框架按钮实现。特别是 AddAttributesToRender 方法。然后您可以修改代码以使其按照您想要的方式工作:
Please have a look at .NET framework Button implementation. Especially AddAttributesToRender method. You can then modify the code to make it works the way you want:
继续 Bui Cuion 你需要的是你的 cs 中的这两件事
1:
和
options.ClientSubmit = false;是秘密
continuing Bui Cuion what you need is these 2 things in your cs
1:
and
options.ClientSubmit = false; is the secret