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

面向数据驱动应用程序的更好的 ValidationSummary 控件

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.71/5 (17投票s)

2002年6月10日

2分钟阅读

viewsIcon

162675

downloadIcon

782

可以通过轻松地对 ValidationSummary 控制进行子类化,从而使数据驱动的 Web 应用程序更易于编写代码。

引言

随 ASP.NET 提供的验证控件在减少 Web 页面中编写的大量繁琐代码方面发挥了重要作用。人们已经在验证控件的概念基础上进行构建,并提供自定义版本以支持许多 Web 应用程序中常见的特定数据类型。我想演示一下 Validation Summary 控制的简单自定义如何大大清理数据驱动的 Web 应用程序中的代码。

尽管验证控件功能强大,但有些验证永远无法在客户端执行。例如,验证用户是否正在向数据库中输入重复信息。CustomValidator 控制是为我们的“自定义”代码设计的,该代码必须验证数据输入,但由于 Web 应用程序固有的事件模型和并发问题,它有些笨拙。请查看下面的代码,看看我的意思。请注意,我们最终得到了一个相当无用的 ServerValidate 事件处理程序。这种方法能够工作的原因是 ValidationSummary 控制足够智能,不会渲染空白条目。即使我们的 CustomValidator 始终无效,输出仍然会是正常的,因为我们的自定义验证器在一切有效时将具有一个空白的错误消息。

private void CustomValidator1_ServerValidate(object source, 
    System.Web.UI.WebControls.ServerValidateEventArgs args) {

    /* Since our 'custom validation' occurs at the database level we can't
    really do anything useful here.  If we checked our database in here for
    duplicates we'd be requiring a database call and plus there could still be
    the chance that another user inserts their data in-between the time we made that
    call and the time we actually did our insert.  Always return false so that our
    real validation code has a chance to set the error message */

    args.IsValid = false;
}

private void SaveButton_Click(object sender, System.EventArgs e) {    

    /* This is where we insert a new record into the database.
    We will get an exception from the data provider if we
    are going to violate any database rules.  If we get that
    exception we want to put a message in the validation 
    summary */

    try {
        BusinessLayer.InsertIntoDatabase(InputField.Text);
        Response.Redirect("success.aspx");
    }
    catch (SqlException ex){
        if (ex.Number == 2601){
            CustomValidator1.ErrorMessage = "That input already exists, try another";
        }
    }

    // All other exceptions are 'unexpected' so let global error handler 
    // deal with them

}

在编写这段代码几次后,我意识到一定有更好的方法。然后我找到了解决方案,只需对 ValidationSummary 控制进行子类化。使用我的自定义控制,我可以根据需要以编程方式添加错误消息。由此产生的代码更加简洁。

private void SaveButton_Click(object sender, System.EventArgs e) {    

    try {
        BusinessLayer.InsertIntoDatabase(InputField.Text);
        Response.Redirect("success.aspx");
    }
    catch (SqlException ex){
        if (ex.Number == 2601){
            CustomSummary.AddErrorMessage("That input already exists, try another");
        }
    }

}
CustomSummary 变量是我的自定义 ValidationSummary 控制的一个实例。在内部,AddErrorMessage 正在创建一个实现 IValidator 接口的内部类实例,并将其添加到页面的 Validators 集合中。现在,我们没有创建新的验证器,ValiationSummary 控制的基本行为通过迭代此集合并显示标记为无效的实例的消息来完成实际工作。
namespace Juranek.Web.Controls {
    /// <summary>
    /// This control inheirits the ASP.NET ValidationSummary control but adds
    /// the ability to dynamically add error messages without requiring 
    /// validation controls.
    /// </summary>
    public class ValidationSummary : System.Web.UI.WebControls.ValidationSummary
    {
        /// <summary>
        /// Allows the caller to place custom text messages inside the validation
        /// summary control
        /// </summary>
        /// lt;param name="msg">The message you want to appear in the summary</param>
        public void AddErrorMessage(string msg) {
            this.Page.Validators.Add(new DummyValidator(msg));
        }
    }

    /// <summary>
    /// The validation summary control works by iterating over the Page.Validators
    /// collection and displaying the ErrorMessage property of each validator
    /// that return false for the IsValid() property.  This class will act 
    /// like all the other validators except it always is invalid and thus the 
    /// ErrorMessage property will always be displayed.
    /// </summary>
    internal class DummyValidator : IValidator {

        private string errorMsg;

        public DummyValidator(string msg) {
            errorMsg = msg;
        }

        public string ErrorMessage{
            get{ return errorMsg;}
            set{ errorMsg = value;}
        }

        public bool IsValid{
            get{return false;}
            set{}
        }

        public void Validate() {
        }
    }

}

总的来说,只需少量代码,就可以创建一个更直观的 ValidationSummary 控制。

© . All rights reserved.