asp.net c中的动态表单创建#

asp.net c中的动态表单创建#,asp.net,vb.net,web-applications,dynamic,webforms,Asp.net,Vb.net,Web Applications,Dynamic,Webforms,因此,我需要对asp.net(c#)应用程序进行一些输入重构,该应用程序基本上是用于创建动态表单(任何表单)的框架。从高层次的角度来看,有一个表包含表单,然后有一个表包含所有表单字段,两者之间是一对多。有一个验证表,其中每个字段可以有多种类型的验证,从表单字段表到验证表是一对多的 因此,问题是,该应用程序已作为可定制的解决方案销售给所有客户。因此,无论他们想要什么形式,我们都可以使用DB配置构建jsut。问题是,这并不总是可能的,因为字段之间存在复杂的关系,表单本身之间也存在复杂的关系。而且,只

因此,我需要对asp.net(c#)应用程序进行一些输入重构,该应用程序基本上是用于创建动态表单(任何表单)的框架。从高层次的角度来看,有一个表包含表单,然后有一个表包含所有表单字段,两者之间是一对多。有一个验证表,其中每个字段可以有多种类型的验证,从表单字段表到验证表是一对多的

因此,问题是,该应用程序已作为可定制的解决方案销售给所有客户。因此,无论他们想要什么形式,我们都可以使用DB配置构建jsut。问题是,这并不总是可能的,因为字段之间存在复杂的关系,表单本身之间也存在复杂的关系。而且,只有一个代码库,这是针对多个客户机的——所有客户机都自己托管代码库。每个客户端都有非常特定的逻辑,它们都在同一个代码库中,没有真正的分离。有时很难将其通用化,因此在某些情况下,它具有硬编码逻辑(例如,如果formID=XXX,那么do u2;)。您也可以有嵌套表单,如中所示,每个表单中都有一组字段

因此,通常,当一个客户端请求更改时,我们进行更改并将其部署到该客户端-但是另一个客户端请求不同的更改,我们进行更改并将其部署到该客户端,但是来自早期客户端的更改破坏了它,并且尝试调试是一件令人头痛的事情,因为一切都是动态的。我们无法回滚之前的更改,因为这样其他客户机就会崩溃

它不是在真正的三层体系结构中完成的——它是一个引用DB类和类库的网站。网站本身、类库和数据库存储过程中都有业务逻辑(验证在存储过程中完成)

我负责重新组织整个事件,以下是我的想法/问题:

  • 我认为这通常是一个糟糕的模型,因为我听到一位开发人员说,任何时候任何客户端进行更改,我们都应该部署到每个人身上——但这是不现实的,如果我们有20个客户端的话——将需要对所有东西进行回归测试,因为我们不知道影响

  • 总共大约有100种形式,它们有一些相似之处(不多)。但我认为动态引擎可以解决所有表单请求的想法也不现实。客户会提出最奇怪的请求。例如,他们让这个引擎做一个常规的数据输入表单和一个搜索表单

  • 页面之间有很多保存状态的功能,都是使用会话变量来完成的,这是可以的,只是它没有被真正跟踪,所以来自同一用户的会话不断被覆盖,我认为会话应该被删除

  • 我真的应该重写整件事吗?这个应用程序已经有3年的历史了,已经做了很多测试和事情,并且实现了严肃的业务逻辑,所以我讨厌摆脱这些(joel的建议)。但这真的是一堆sphagetti代码,每件事都要花很长时间才能完成,而且由于一些小的更改,事情总是会中断

  • 我一直在读Martin Fowlers的《重构》和Michael Feathers的《有效地处理遗留代码》——它们都很好,但我觉得它们是为一个架构“稍微”好一点的应用程序编写的,在这个应用程序中,它仍然是一个三层架构,并且在逻辑上有一些类似之处

    思考/输入任何人


    哦,还有“帮助!”

    我有许多类似的应用程序,用于构建我支持的动态表单

    有很多事情你可以做/不能做&在扔掉3年的测试/开发之前,你好好想想是对的

    我想让你考虑的是在你所得到的基础上实现一个插件体系结构。表单的任何自定义代码都会进入插件&该插件的名称与表单一起存储。生成表单时,将调用正确的插件以增强基本功能。这样就可以将所有自定义代码移出现有库。它还应该意味着更少的破坏性更改,每个插件只影响它所附加到的表单


    从那时起,重构核心引擎就很容易了,因为它是所有客户机和表单的通用功能。

    我当前的项目听起来几乎与您描述的产品完全相同。幸运的是,我从以前的一款产品中学到了最难的一课,因此我能够从头开始我当前的项目。你也许应该通读一遍,它描述了我的经历,以及我学到的教训

    最重要的是要关注你正在构建一个产品的想法。如果您无法找到使用当前产品功能集实现特定功能的方法,则需要花一些额外的时间考虑如何将此自定义一次性功能转变为可配置功能,从而使所有(或至少许多)客户受益

    因此:

  • 如果您指的是能够创建一个完全可定制的表单的模型,该表单使得特定于客户端的代码几乎不必要,那么该模型是完全有效的,我有一个可维护的工作产品,可以与真实的付费客户一起证明这一点。回归测试是在特定的特性和配置组合上执行的,而不是特定的客户端实现。实现这一目标的关键是:
  • 一种管理界面,有效地禁止有问题的配置选项组合
  • 一种规则引擎,允许系统中的某些操作调用可自定义的触发器并导致其他操作发生
  • 允许dat的集成框架
    {Type:"FormDefinition",
     EntityType: "Customer",
     Fields: [
       {FieldName:"CustomerName", 
        FieldType:"String", 
        Validations:[
          {ValidationType:"Required"},
          {ValidationType:"StringLength", Minimum:15, Maximum:50},
        ]},
        ...
       {FieldName:"CustomerType", 
        FieldType:"Dropdown", 
        PossibleValues: ["Standard", "Valued", "Gold"],
        DefaultValue: ["Standard"]
        Validations:[
          {ValidationType:"Required"},
          {
            ValidationType:"Custom", 
            ValidationClass:"MySystem.CustomerName.CustomValidations.CustomerStatus"
          }
        ]},
        ...
     ]
    };
    
    namespace System.CustomerName.CustomValidations {
      class CustomerStatus: IValidator {
    
        private FormContext form;
        private List<ValidationErrors> validationErrors;
    
        CustomerStatus(FormContext fc) {
          this.validationErrors = new List<ValidationErrors>();
          this.form = fc;
        }
    
        public List<ValidationErrors> Validate() {
          if (this.formContext.Fields["CustomerType"] == "Gold" && Int.Parse(this.form.Fields["OrderCount"]) < 10) { 
            this.validationErrors.Add(new ValidationError("A gold customer must have at least 10 orders"))
          }
    
          if (this.formContext.Fields["CustomerType"] == "Valued" && Int.Parse(this.form.Fields["OrderCount"]) < 5) { 
            this.validationErrors.Add(new ValidationError("A valued customer must have at least 5 orders"))
          }
          return this.validationErrors;          
        }
      }
    }
    
    {Type:"Record",
     EntityType: "Customer",
     Fields: [
       {FieldName:"CustomerName", Value:"ABC Corp.", 
       {FieldName:"CustomerType", Value:"Gold",
       ...
     ]
    };