简体   繁体   English

还有更好的方法来处理用户输入验证吗?

[英]Any better way to handle user input validation?

I have a 3 layered system of presentation, logic, and data access. 我有一个三层的演示,逻辑和数据访问系统。 In my logic layer, I have a Validate() method which makes sure that the data that's about to get forwarded to the data access layer is valid for the database (no nulls where nulls are not allowed, and so on). 在我的逻辑层中,我有一个Validate()方法,该方法确保将要转发到数据访问层的数据对数据库有效(不允许有null,不允许存在null,等等)。

On top of that, in the .aspx presentation layer, we have some user-friendly error checking and validation, directly checking the controls on the web form. 最重要的是,在.aspx表示层中,我们进行了一些用户友好的错误检查和验证,可直接检查Web窗体上的控件。 My problem is the ValidateInput() method in the code behind which checks the controls, it's several hundreds of lines long and really annoying to maintain. 我的问题是代码中的ValidateInput()方法,该方法在后面检查控件,它的长度为几百行,维护起来确实很烦人。 The code for checking the data is far far longer than the code that does the actual work. 用于检查数据的代码远比执行实际工作的代码长得多。

What I've got looks like this: 我所拥有的看起来像这样:

        private List<string> ValidateInput()
        {
           List<string> errormessages = new List<string>();

           if (LastNameETextBox.Text.Trim() == String.Empty)
           { 
              errormessages.Add("Last name required."); 
           }

           if (FirstNameETextBox.Text.Trim() == String.Empty)
           { 
              errormessages.Add("First name required."); 
           }

           //etc. etc.
        }

We have a nice styled notification box hidden in the master page that gets turned from Visible false to true when we call it, creating the "illusion" of an overlaying box. 我们在母版页中隐藏了一个漂亮的通知框,当我们调用它时,它从Visible false变为true,从而创建了一个覆盖框的“错觉”。 It looks really nice and works really well so we want to use it. 它看起来非常好,并且工作得非常好,因此我们想使用它。 The idea is that we gather up all the errors for the whole form, put them in a list, and then send that list to the notification box, which then gives you all the errors in one nice list. 想法是,我们收集整个表单的所有错误,将它们放入列表中,然后将该列表发送到通知框,然后通知框将所有错误集中在一个不错的列表中。

But the Validate() is just a torturous amount of "if" statements and it's hard to keep track of. 但是Validate()只是“ if”语句的折腾而已,很难跟踪。 Is this just the nature of input validation, or is there some other, better way of handling this? 这仅仅是输入验证的本质,还是还有其他更好的方法来处理呢?

I think you can able to avoid using these kind of If statements using a Generic function. 我认为您可以避免通过Generic函数使用此类If语句。 My suggestion is to define a function like this 我的建议是定义一个这样的功能

private List<string> ValidateInput(string ErrorMessage, TextBox txtInput, ValidatationType validationType)
{
    List<string> errormessages = new List<string>();


    if (validatationType  == ValidationType.NoNullValues)
    { 

        if (txtInput.Text.Equals(String.Empty))
            {
                errormessages.Add(ErrorMessage); 
            }

    }

    if (validatationType  == ValidationType.Integer)
    { 

        int number;
        if (Int32.TryParse(value, out number))
        {
            errormessages.Add(ErrorMessage); 
        }

    }

    // etc. etc.
}

Enum ValidationType 枚举ValidationType

enum ValidationType
{
    NoNullValues,
    Integer,
    // etc
}

Please modify the function. 请修改功能。 Also checks the syntax, I am using notepad to write the code. 还检查语法,我正在使用记事本编写代码。 This approach also helps you to achieve re-useabilty if you are use all validation methods in a separate class. 如果您在单独的类中使用所有验证方法,则此方法还可以帮助您实现重用性。

Thanks 谢谢

Couple of the different ways that I had handled it (in different projects) : 我处理它的几种不同方式(在不同项目中):

  1. Use custom control library - controls were simply extending existing ASP.NET/3rd party controls to add validation logic which was controlled by properties such as IsMandatory, MandatoryMessage etc. Properties were typically set at the design-time (and were not backed by view-state). 使用自定义控件库-控件只是扩展了现有的ASP.NET/3rd控件,以添加验证逻辑,该逻辑由IsMandatory,MandatoryMessage等属性控制。属性通常是在设计时设置的(并且不由view-back支持)州)。 The validation logic would accumulate error messages in the message collection exposed by base page. 验证逻辑将在基本页公开的消息集中累积错误消息。 Another variant had used user controls combining ASP.NET controls along with validators but frankly speaking, ASP.NET validators sucks. 另一个变体使用结合了ASP.NET控件和验证器的用户控件,但坦率地说,ASP.NET验证器很烂。

  2. Essentially a base page class had a validation logic that would traverse the control collection within the page and then perform validation based on control type. 本质上,基本页面类具有验证逻辑,该逻辑将遍历页面内的控件集合,然后根据控件类型执行验证。 The page would offer a registry to register control to validate, type of validations and error message to display. 该页面将提供一个注册表,用于注册要验证的控件,要验证的类型和要显示的错误消息。 There was also method to un-register/skip control validation that was used primarily to skip control traversal within control such as repeater/grid-view. 还有一种取消注册/跳过控件验证的方法,该方法主要用于跳过控件(如转发器/网格视图)中的控件遍历。

For client-side(browser side) validation, I had used jquery validation (or own JS library). 对于客户端(浏览器端)验证,我使用了jquery验证 (或自己的JS库)。 In both cases above, the validation logic would also emit necessary start-up scripts to set-up the client-side validation - however, #2 could generate a single start-up script (with less size) while #1 entails generating a start-up script per control instance. 在上述两种情况下,验证逻辑还将发出必要的启动脚本以设置客户端验证-但是,#2可以生成一个启动脚本(具有较小的大小),而#1则需要生成一个启动每个控制实例的脚本。 From flexibility perspective, #1 is better and fits nicely in control based development approach. 从灵活性的角度来看,#1更好,并且非常适合基于控件的开发方法。 #2 centralizes your validation logic at one central place (ie a base page) which can be very handy. #2将验证逻辑集中在一个非常方便的中心位置(即基本页面)。

a) Create an validation type enum to enumerate all types of validation you want to perform. a)创建一个验证类型枚举,以枚举您要执行的所有验证类型。 (In your code you are doing string null checking for both controls which are both textboxes, its unnecessary repetition of code logic) b) Create a class of constants / or resource file that holds all the error messages. (在您的代码中,您正在对两个都是文本框的控件进行字符串null检查,这是不必要的代码逻辑重复)b)创建一个常量类或包含所有错误消息的资源文件。 c) Write a function that takes a control, Validation type enum, arguments for validation and error message id. c)编写一个函数,该函数带有一个控件,Validation类型枚举,用于验证的参数和错误消息ID。 It will check the type of control and perform validation as indicated by enum. 它将检查控件的类型并执行枚举指示的验证。 If error, error message is added to your "errorMessages" collection. 如果出错,错误消息将添加到“ errorMessages”集合中。

enum ValidationType{
    NullCheck,
    IsNumber,
    RangeCheck,
    ....
}

class ErrorMessages{
    const string FNEMPTY = "First Name is empty";
    ....
}

class BusinessObject{
    function ValidateControl(Control cntrl, ValidationType type, object[] args, string message)
    {
        if(cntrl is TextBox)
        {
             if(cntrl as TextBox).Text.Trim() == String.Empty
                  errorMessages.Add(message);
        }
        ...
    }
}

Now you can call the above function on every control you want to validate. 现在,您可以在要验证的每个控件上调用上述函数。 One more improvement will be to Implement a base class for all your controls that holds the corresponding error message collection in a property (Dictionary<ValidationType,String>) . 另一个改进将是为所有控件实现一个基类,该基类将相应的错误消息集合保存在属性(Dictionary<ValidationType,String>) Then you can modify the validation function to accept an array of ValidationType enum to perform several validation in one call. 然后,您可以修改验证函数以接受一个ValidationType枚举数组,以在一个调用中执行多个验证。 Each control will give you its error message for every validation type in its property we created in the base class. 每个控件都会在我们在基类中创建的属性中为您提供每种验证类型的错误消息。

Hope this helps. 希望这可以帮助。

Thanks Ven 感谢Ven

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM