lsu*_*rez 2 asp.net validation webforms custom-server-controls clientscriptmanager
我正在创建一个自定义服务器控件来为我的Web窗体应用程序生成带有特定标记和JavaScript处理程序的按钮元素.当然,它们能够导致回发,因此我希望它们能够与ASP的任何验证控件一起使用,以进行表单验证,尤其是客户端框架.
此按钮服务器控件支持使用提供的代码在按钮标记中OnClientClick发出onclick属性的属性(主要用于当用户单击列表视图的删除按钮或类似时的简单确认重新提示),因此使用asp:Button控件的方法发出验证脚本作为onclick属性将非常无效.事实上,在标准上指定两者OnClientClick和ValidationGroup属性asp:Button结果非常糟糕.这是一个非常明显的例子,说明为什么不能开箱即用:
页面标记
<asp:Button ID="btnSaveAsp" ValidationGroup="vgMyValidationGroup" OnClientClick="return true;" runat="server" />
Run Code Online (Sandbox Code Playgroud)
呈现标记
<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))'>
Run Code Online (Sandbox Code Playgroud)
以下是现有的非工作代码,用于通过验证对控件进行连接.除了发出类似的onclick属性之外,我无法找到关于如何使用方法实现此目的的更多文档.我认为我Page.ClientSCript.RegisterForEventValidation在重写AddAttributesToRender方法中的调用将连接客户端验证,但这似乎没有像我假设的那样起作用.如有必要,jQuery可用于绑定对按钮的click事件的附加处理:
自定义服务器按钮控件
<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
Run Code Online (Sandbox Code Playgroud)
目前,此代码不能asp:CompareValidator同时ValidationGroup用于确定在发回服务器之前两个密码重置字段是否相等,一旦请求到达服务器端也不会发生验证.
制作OnClientClick与客户端表单验证工作
由于<asp:Button>控件OnClientClick将表单验证脚本的值连接在一起,因此最简单的方法是return false在您希望阻止表单提交时,如果您希望按钮验证并提交表单,则无需执行任何操作:
OnClientClick="if (!confirm('Are you sure?')) return false;"
Run Code Online (Sandbox Code Playgroud)
但是,如果您绝对想要编写return confirm('Are you sure?'),那么您可以将表单验证代码移动到事件监听器(如您所建议的那样),或者您可以OnClientClick像这样包装代码:
writer.AddAttribute(
HtmlTextWriterAttribute.Onclick,
"if (!(function() { " + this.OnClientClick + "; return true; })()) return false;" +
this.Page.ClientScript.GetPostBackEventReference(options, false));
Run Code Online (Sandbox Code Playgroud)
服务器端表单验证
您需要实现IPostBackEventHandler接口并调用该Page.Validate方法.该ClientScriptManager.RegisterForEventValidation方法用于事件验证(防止未经授权或恶意回发),而不用于表单验证.
示例代码(C#)
以下是支持OnClientClick和支持的简单自定义按钮控件的代码ValidationGroup:
[ParseChildren(false)]
[PersistChildren(true)]
public class Button : WebControl, IPostBackEventHandler
{
private static readonly object EventClick = new object();
public Button()
: base(HtmlTextWriterTag.Button)
{
}
public bool CausesValidation
{
get { return ((bool?)this.ViewState["CausesValidation"]) ?? true; }
set { this.ViewState["CausesValidation"] = value; }
}
public string ValidationGroup
{
get { return (string)this.ViewState["ValidationGroup"] ?? ""; }
set { this.ViewState["ValidationGroup"] = value; }
}
public string OnClientClick
{
get { return (string)this.ViewState["OnClientClick"] ?? ""; }
set { this.ViewState["OnClientClick"] = value; }
}
public event EventHandler Click
{
add { this.Events.AddHandler(EventClick, value); }
remove { this.Events.RemoveHandler(EventClick, value); }
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
if (this.Page != null && this.Enabled)
{
PostBackOptions options = this.GetPostBackOptions();
writer.AddAttribute(
HtmlTextWriterAttribute.Onclick,
this.OnClientClick + this.Page.ClientScript.GetPostBackEventReference(options, false));
}
}
protected virtual PostBackOptions GetPostBackOptions()
{
PostBackOptions options = new PostBackOptions(this) { ClientSubmit = false };
if (this.Page != null)
{
if (this.CausesValidation && this.Page.GetValidators(this.ValidationGroup).Count > 0)
{
options.PerformValidation = true;
options.ValidationGroup = this.ValidationGroup;
}
}
return options;
}
protected virtual void OnClick(EventArgs e)
{
EventHandler handler = (EventHandler)this.Events[EventClick];
if (handler != null)
{
handler(this, e);
}
}
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
if (this.CausesValidation)
{
this.Page.Validate(this.ValidationGroup);
}
this.OnClick(EventArgs.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7685 次 |
| 最近记录: |