C# 文本框控件的链接必填字段和正则表达式验证器问题
我正在尝试用ASP.net实现表单验证,我已经尝试了所有建议的解决方案,但迄今为止最好的解决方案还在使用中 我的代码如下:C# 文本框控件的链接必填字段和正则表达式验证器问题,c#,asp.net,validation,webforms,C#,Asp.net,Validation,Webforms,我正在尝试用ASP.net实现表单验证,我已经尝试了所有建议的解决方案,但迄今为止最好的解决方案还在使用中 我的代码如下: <asp:TextBox ID="tTitle" runat="server" onblur="WebForm_OnBlur()"/> <asp:RequiredFieldValidator runat="server" ControlToValidate="tTitle"/> <asp:TextBox ID="tEMail" runat="
<asp:TextBox ID="tTitle" runat="server" onblur="WebForm_OnBlur()"/>
<asp:RequiredFieldValidator runat="server" ControlToValidate="tTitle"/>
<asp:TextBox ID="tEMail" runat="server" onblur="WebForm_OnBlur()"/>
<asp:RequiredFieldValidator runat="server" ControlToValidate="tEMail"/>
<asp:RegularExpressionValidator runat="server" ControlToValidate="tEMail"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"/>
<asp:LinkButton ID="btnSubmit" runat="server" Text="Submit"/>
Javascript
<script type="text/javascript">
function WebForm_OnSubmit() {
if (typeof (ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false)
{
for (var i in Page_Validators) {
try {
var control =
document.getElementById(Page_Validators[i].controltovalidate);
if (!Page_Validators[i].isvalid) {
control.className = "error";
} else {
control.className = "";
}
} catch (e) { }
} return false;
} return true;
}
function WebForm_OnBlur() {
for (var i in Page_Validators) {
try {
var control =
document.getElementById(Page_Validators[i].controltovalidate);
if (!Page_Validators[i].isvalid) {
control.className = "error";
} else {
control.className = "";
}
} catch (e) { }
} return false;
}
</script>
函数WebForm_OnSubmit(){
if(typeof(ValidatorOnSubmit)=“函数”&&ValidatorOnSubmit()==false)
{
用于(第页验证程序中的var i){
试一试{
无功控制=
document.getElementById(Page_Validators[i].controltovalidate);
如果(!Page_Validators[i].isvalid){
control.className=“error”;
}否则{
control.className=“”;
}
}捕获(e){}
}返回false;
}返回true;
}
函数WebForm_OnBlur(){
用于(第页验证程序中的var i){
试一试{
无功控制=
document.getElementById(Page_Validators[i].controltovalidate);
如果(!Page_Validators[i].isvalid){
control.className=“error”;
}否则{
control.className=“”;
}
}捕获(e){}
}返回false;
}
问题是电子邮件字段只验证正则表达式。如果我更改验证器的顺序,它只验证所需的表达式
可能的问题是,代码在所有验证器中循环,但不会同时比较引用同一控件的验证器。这将导致仅对控件应用最后一个验证器条件
可能的问题是,代码在所有验证器中循环,但不会同时比较引用同一控件的验证器。这将导致仅对控件应用最后一个验证器条件
是的,这确实是问题所在。要修复它,可以执行以下操作:
在WebForm\u OnBlur
函数中,循环通过与失去焦点的控件相关联的验证器(而不是页面上的所有验证器),并仅在所有验证器都有效时清除className
属性:
function WebForm_OnBlur(control) {
for (var i = 0; i < control.Validators.length; i++) {
if (!control.Validators[i].isvalid) {
control.className = "error";
return;
}
}
control.className = "";
}
在WebForm\u OnSubmit
函数中,为每个具有关联验证器的控件调用WebForm\u OnBlur
:
function WebForm_OnSubmit() {
if (typeof(ValidatorOnSubmit) === "function" && ValidatorOnSubmit() === false) {
for (var i = 0; i < Page_Validators.length; i++) {
var control = document.getElementById(Page_Validators[i].controltovalidate);
if (Page_Validators[i] === control.Validators[0]) // minor optimization
WebForm_OnBlur(control);
}
return false;
}
return true;
}
函数WebForm_OnSubmit(){
if(typeof(ValidatorOnSubmit)==“函数”&&ValidatorOnSubmit()==false){
对于(变量i=0;i
您可以在javascript中尝试Page_ClientValidate(),而不是在验证程序之间循环。
我相信这将验证页面上的所有验证器。
如果要验证由特定验证组绑定的特定控件,它还将引入参数“验证组名称”。除了@MichaelLiu,您可以创建自己的验证器,该验证器继承自
CustomValidator
类,并更改验证器的呈现方式,使其更易于使用
例如:
验证程序
注意我们如何添加
CssControlErrorClass
的属性。我们将在应用带有所讨论的无效输入的类时使用它
我们还设置了其他属性,因此您不必每次都设置它们,ClientValidationFunction
和ValidateEmptyText
public class RequiredFieldValidator : CustomValidator
{
public string CssControlErrorClass { get; set; }
public RequiredFieldValidator()
{
ClientValidationFunction = "validators.required";
ValidateEmptyText = true;
}
public string InitialValue
{
get
{
object o = ViewState["InitialValue"];
return ((o == null) ? String.Empty : (string)o);
}
set
{
ViewState["InitialValue"] = value;
}
}
protected override void Render(HtmlTextWriter writer)
{
//Have to add attributes BEFORE the beginning tag is written to the stream
writer.AddAttribute("data-errorClass", CssControlErrorClass);
writer.AddAttribute("data-for", GetControlRenderID(ControlToValidate));
base.Render(writer);
}
protected override bool EvaluateIsValid()
{
//Default implementation of the RequiredFieldValidation validator
string controlValue = GetControlValidationValue(ControlToValidate);
if (controlValue == null)
{
return true;
}
var result = (!controlValue.Trim().Equals(InitialValue.Trim()));
//Check to see if validation failed, if it did, add the class to the control to validate
if (!result)
{
var control = (WebControl) NamingContainer.FindControl(ControlToValidate);
//Didn't look into it too much, but the validators fire twice for some reason
if(!control.CssClass.Contains(CssControlErrorClass)) control.CssClass += " " + CssControlErrorClass;
}
return result;
}
}
public class RegularExpressionValidator : CustomValidator
{
public string CssControlErrorClass { get; set; }
public string ValidationExpression
{
get
{
object o = ViewState["ValidationExpression"];
return ((o == null) ? String.Empty : (string)o);
}
set
{
try
{
Regex.IsMatch(String.Empty, value);
}
catch (Exception e)
{
throw new HttpException(string.Format("{0} - {1}", "Validator_bad_regex", value), e);
}
ViewState["ValidationExpression"] = value;
}
}
public RegularExpressionValidator()
{
ClientValidationFunction = "validators.regex";
}
protected override void Render(HtmlTextWriter writer)
{
//Have to add attributes BEFORE the beginning tag is written to the stream
writer.AddAttribute("data-errorClass", CssControlErrorClass);
writer.AddAttribute("data-regex", ValidationExpression);
writer.AddAttribute("data-for", GetControlRenderID(ControlToValidate));
base.Render(writer);
}
protected override bool EvaluateIsValid()
{
//Default implementation of the RegularExpressionFieldvalidator
string controlValue = GetControlValidationValue(ControlToValidate);
if (controlValue == null || controlValue.Trim().Length == 0)
{
return true;
}
try
{
Match m = Regex.Match(controlValue, ValidationExpression);
var result = (m.Success && m.Index == 0 && m.Length == controlValue.Length);
//Check to see if validation failed, if it did, add the class to the control to validate
if (!result)
{
var control = (WebControl) NamingContainer.FindControl(ControlToValidate);
//Didn't look into it too much, but the validators fire twice for some reason
if (!control.CssClass.Contains(CssControlErrorClass)) control.CssClass += " " + CssControlErrorClass;
}
return result;
}
catch
{
return true;
}
}
}
Validators.js
因为在前面的类中我们预定义了javascript函数,所以我们可以添加如下简单脚本:
var v = window.validators = window.validators || {
errorControlAttributeName: "data-for",
errorClassAttributeName: "data-errorClass",
regexAttributeName: "data-regex",
required: function(src, args) {
var controlId = src.getAttribute(v.errorControlAttributeName),
errorClass = src.getAttribute(v.errorClassAttributeName),
input = document.getElementById(controlId);
var isValid = (args.Value !== "");
v._toggleInputErrorState(input, errorClass, isValid);
args.IsValid = isValid;
return;
},
regex: function(src, args) {
var controlId = src.getAttribute(v.errorControlAttributeName),
errorClass = src.getAttribute(v.errorClassAttributeName),
regexString = src.getAttribute(v.regexAttributeName),
input = document.getElementById(controlId),
regex = new RegExp(regexString);
var isValid = regex.test(args.Value);
v._toggleInputErrorState(input, errorClass, isValid);
args.IsValid = isValid;
return;
},
/************* Helper functions ***********/
_toggleInputErrorState: function (inputEl, errorClass, isValid) {
if (!isValid) {
if (!v._hasClass(inputEl, errorClass)) {
inputEl.className += " " + errorClass;
}
} else {
if (v._hasClass(inputEl, errorClass)) {
//Not the most performant, but is sure is easiest
inputEl.className = inputEl.className.replace(" " + errorClass, "");
}
}
},
_hasClass: function(el, className) {
return el.className.indexOf(className) != -1 ? true : false;
},
}
非常简单的验证库,您可以很容易地扩展您真正感兴趣的内容
Default.aspx
之后,您可以将控件放入页面:
<Validators:RequiredFieldValidator runat="server" CssControlErrorClass="input-validation-error" ControlToValidate="Test" ErrorMessage="REQUIRED BRO!"></Validators:RequiredFieldValidator>
<Validators:RegularExpressionValidator runat="server" ValidationExpression="[0-9]" CssControlErrorClass="input-validation-error" ControlToValidate="Test" ErrorMessage="REQUIRED RegEx BRO!"></Validators:RegularExpressionValidator>
这是最好的方式吗?可能不会,(这两个使用微软提供的默认实现)有很多比我更聪明的人,我和我很少使用WebForms。我看到的最大好处是,您可以使用熟悉的语法获得一些可重用的代码,这些代码最终将包含您所有的验证需求,而不是每次都使用js来获取您想要的验证“规则”。通过替换下面的代码片段,解决了这个问题。为了纠正错误,我们必须循环检查控件的所有验证器,然后我们应该决定是否必须用错误类标记它。在此之后,您的代码将按预期工作 更换回路
for (var i in Page_Validators) {
try {
var control =
document.getElementById(Page_Validators[i].controltovalidate);
if (!Page_Validators[i].isvalid) {
control.className = "error";
} else {
control.className = "";
}
} catch (e) { }
}
用下面的代码
for (var j in Page_Validators) {
try {
var control =
document.getElementById(Page_Validators[j].controltovalidate);
var IsError = false;
for (var i in control.Validators) {
if (!control.Validators[i].isvalid) {
IsError = true;
}
}
if (IsError)
control.className = "error";
else
control.className = "";
} catch (e) { }
}
我刚刚运行了它,它工作得很好:)试试这个解决方案 创建服务器端自定义验证器怎么样。我不再做太多的网页表单开发了。但我想我在2010年做过一些基于服务器的自定义验证器。下面是一个有用的例子:good luckw在测试期间,您在
tEmail
字段中输入的值是什么?是的,创建一个自定义控件将解决这个问题@qamar.value取决于验证器对tEmail字段的顺序。我不确定问题是什么-您没有显示所有验证错误,还是没有触发所有验证错误验证器?另请注意——确保您也在验证服务器端,而不仅仅是客户端。客户端验证可以很容易地绕过。那么将css类添加到无效控件中又如何呢?
for (var j in Page_Validators) {
try {
var control =
document.getElementById(Page_Validators[j].controltovalidate);
var IsError = false;
for (var i in control.Validators) {
if (!control.Validators[i].isvalid) {
IsError = true;
}
}
if (IsError)
control.className = "error";
else
control.className = "";
} catch (e) { }
}