【问题标题】:Best Practices for controlling access to form fields控制对表单字段的访问的最佳实践
【发布时间】:2008-12-15 16:25:59
【问题描述】:

我有一个经典的 3 层 ASP.Net 3.5 Web 应用程序,它带有显示业务对象并允许对其进行编辑的表单。表单上的控件对应于底层业务对象的属性。根据他/她的角色,用户将对各种控件具有读/写、只读或无访问权限。非常传统的东西。

我的问题是:编写此代码的面向对象的最佳实践是什么?有什么比将每个控件包装在用户角色测试中并设置其 Visible 和 Enabled 属性更优雅的方法?

谢谢

【问题讨论】:

    标签: asp.net


    【解决方案1】:

    相信我,您会希望将其从数据中剔除。你需要很多表才能做到这一点,但最终还是值得的。每次企业想要更改权限时,都必须破解开放代码并编辑一堆 if 语句是一个杀手。

    您需要一个用于主要高级类型的表,您可能已经有业务对象类。然后是他们每个状态的表格。然后是这些类的字段的表。然后是用户角色(管理员、访客等)的表。最后是权限本身的表。此表将包含业务类、状态、字段、用户角色以及他们拥有的权限的列。对于权限,我会使用一个字段并使用枚举:隐藏、只读、可编辑和必需。必需意味着可编辑。除了隐藏之外的任何东西都意味着可见。最后在这张表上放一个 Priority 列,以控制在可能应用多个权限时使用哪个权限。

    您使用类、状态、字段、角色和权限的各种组合来填写此表。如果一个值为空,那么它适用于所有可能的值。所以你不需要一万亿行来覆盖你所有的基地。例如,在 99% 的情况下,来宾用户都是只读用户。因此,您可以在表中放置一个条目,仅指定 Guest 角色,其他所有内容为空,并将其设置为优先级好和高,并将权限设置为只读。现在对于所有课程、所有状态、所有字段,如果用户是访客,他们将拥有只读权限。

    我将状态添加到您的关注列表中,因为根据我的经验,企业一直希望通过对象的状态来限制事物。因此,例如,也许用户可以在项目处于草稿状态时编辑项目的名称,但是一旦处于已发布状态,名称就不再可编辑。这在我的经验中很常见。

    您希望将此表放入内存并将其存储在应用程序的缓存中,因为它不会经常更改(如果有的话),除非您制作一个全新的版本。

    我怀疑以上内容将满足您 90% 的需求。

    一个必须在代码中处理的领域,除非您想变得非常花哨,否则用户的权限部分由对象 本身。假设你有一个 Project 类,它有一个 Project Manager 类。现在,类的 Percent Complete 字段基本上对所有人都是只读的,除了项目经理。你打算怎么处理?您需要提供一种将类的特定实例合并到决策制定过程中的方法。我在代码中这样做。

    【讨论】:

      【解决方案2】:

      为了正常工作,我发现访问级别应该按以下递增顺序: 无,查看,必填,编辑。

      请注意,REQUIRED 不是您可能认为的最高级别,因为 EDIT(填充和取消填充权限)比 REQUIRED(仅填充权限)具有更大的权限。

      枚举看起来像这样:

      /** NO permissions.
       *     Presentation: "hidden"
       *     Database: "no access"
       */
      NONE(0),
      
      /** VIEW permissions.
       *     Presentation: "read-only"
       *     Database: "read access"
       */
      VIEW(1),
      
      /** VIEW and POPULATE permissions.
       *     Presentation: "required/highlighted"
       *     Database: "non-null"
       */
      REQUIRED(2),
      
      /** VIEW, POPULATE, and DEPOPULATE permissions.
       *     Presentation: "editable"
       *     Database: "nullable"
       */
      EDIT(3);
      

      从底层(数据库约束)创建要访问的字段映射。然后,此地图在下一层(业务规则 + 用户权限)得到更新(进一步限制)。最后,如果需要,顶层(表示规则)可以进一步限制地图。

      重要提示:地图必须被包装,以便它只允许在任何后续更新时减少访问。试图增加访问权限的更新应该被忽略而不触发任何错误。这是因为它应该像一个投票系统一样决定访问应该是什么样子。本质上,上述访问级别的后续分层可以按任何顺序进行,因为一旦所有层都投票,这将导致每个字段的访问级别低水位标记。

      后果:

      1) 表示层可以为数据库指定的只读 (VIEW) 字段隐藏一个字段(将访问权限设置为 NONE)。

      2) 当业务规则说用户至少没有 VIEW 访问权限时,表示层不能显示字段。

      3) 如果数据库说它只是“必需”(不可为空),则表示层不能将字段的访问权限上移至“可编辑”(可空)。

      注意:应该使表示层(自定义显示标签)通过读取访问映射来呈现字段,而不需要任何“if”语句。

      用于设置显示的相同访问映射也可以在提交验证期间使用。可以编写通用验证器来读取任何表单及其访问映射,以确保遵循所有规则。

      【讨论】:

        【解决方案3】:

        我经常发现这确实是唯一真正简单易懂的方法,因为您的界面需要根据他们可以完成的信息和编辑级别进行修改。

        我确实发现通常情况下,根据需要,如果您计划移动到不同的表示级别,您可以通过将角色信息传递到业务级别来插入“无法编辑”信息。但这增加了复杂性,如果你只为一个接口构建它很可能是矫枉过正

        【讨论】:

          【解决方案4】:

          我以更面向对象的方式执行此操作的第一直觉是处理您的角色及其为此目的的实现(控制权限读/写/等)是为您的角色使用抽象工厂模式。如果您愿意,我很乐意解释我所说的内容的来龙去脉,但网络上可能有 900 个示例。这是one link(免责声明:这是我的博客,但它确实谈到了专门针对角色使用抽象工厂)

          使用类似的方法,您可以使用多种方法来显示具有正确属性(读/写/隐藏/显示/等)的每个业务对象属性的正确控件。

          【讨论】:

            【解决方案5】:

            对于网站菜单,我们可以使用站点地图根据用户角色提供不同的菜单。对于像按钮这样的控件,我们将不得不使用它们的 Visible 属性来隐藏它们。我认为一个好主意是创建一个服务器控件(按钮)并公开 Role 属性。如果用户不是正确的角色,这将隐藏按钮。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-07-31
              • 2010-09-21
              • 2011-01-27
              相关资源
              最近更新 更多