代码之家  ›  专栏  ›  技术社区  ›  newdayrising

Web应用程序中的自定义行为

  •  0
  • newdayrising  · 技术社区  · 15 年前

    我正在开发一个ASP.NET WebForms项目,我们需要能够根据当前用户的“组”在整个应用程序中配置行为。这几乎适用于应用程序的所有方面,包括站点导航、在页面上显示/隐藏某些用户控件以及在某些情况下执行自定义业务逻辑。然而,绝大多数应用程序行为是在组之间共享的,因此我们排除了创建完全独立的应用程序的想法。

    本质上,我要寻找的是在ASP.NET WebForms应用程序中实现自定义行为的体系结构方法。有没有比在视图层、业务层和持久性层的整个代码库中散布if/else语句更好的方法?

    编辑 :一些示例:

    • 如果A组中的用户 导航将包括 从B组加上一些导航 其他链接。

    • 如果用户位于A组,则页面将 显示用户控件c1、c2和c3。 如果用户属于B组,他们将 仅见同一页的C1和C3。

    • 如果用户在窗体上保存了一些数据 他们在A组,发送 通知电子邮件。如果用户是 在B组中,发送文本消息 相反。

    我们可以解决所有这些特定的问题,但是我们正在寻找一种方法来尽可能地封装这种行为,这样它就不会分散在代码库中。

    编辑 :有一些有趣的答案与动态加载用户控件有关。根据用户组确定要加载的控件或要使用的行为的逻辑是否封装在一个(非内聚)类中,例如:

    GroupManager.GetNavigationControl(int groupId) // loads site nav control based on group
    GroupManager.PerformNotification(int groupId) // sends text or email based on group
    

    或者,这个逻辑是否应该尽可能靠近使用它的代码中的位置,从而分布在代码库的不同层?

    4 回复  |  直到 15 年前
        1
  •  1
  •   Mitch A    15 年前

    嗯,没有 这里将详细介绍,但我怀疑您可能会从多态性(即各种接口实现)中获益,以处理不同用户组之间的应用程序部分。控制容器的反转 Spring.NET 可以帮助您根据当前用户角色连接/配置这些不同的实现。您还可以从Spring面向方面的编程API中获益,在该API中,您可以在业务层/数据访问层中修饰方法,以便执行授权逻辑。

        2
  •  1
  •   Chase Florell    15 年前

    “团体”是指“角色”吗?如果你在谈论角色,你可以通过这样做来设定你的行为。

    If User.IsInRole("SomeRandomRole") Then
         'Do some random behavioral crap
    ElseIF User.IsInRole("TheCoolRole") Then
         'Do some cool behavioral crap
    Else
         'Do generic crap
    End If
    

    另一种选择可能是使用基于角色的用户控件。因此,当您有页面加载时,它将基于请求它的角色加载一个用户控件。

    您可以让一个占位符空着,并从codebehind调用loadcontrol方法。

    那么所有用户控件都将与您的角色匹配

    角色=admin usercontrol=admin.ascx
    角色=用户usercontrol=用户.ascx

        3
  •  1
  •   pb.    15 年前

    我认为,在不太详细地讨论IOC等问题的情况下,我会保持它非常简单,并且有一个简单的旧工厂类,您可以使用它根据当前发出请求的用户返回适当的实例化的UI元素[用户控件]。在执行此操作时,您将在一个位置拥有所有“if”语句。要用“if”语句来表示,您只需创建一个映射配置文件或db表,其中包含对用户控件的引用,以便在用户属于特定组时使用。

    注意:这两个选项都将导致在页面上创建动态控件,这并不是没有它自己的复杂性,但我已经在应用程序中成功地使用了一段时间了,没有问题-这只是一个问题,让页面生命周期变得越来越脏,比我最初感觉舒服。

        4
  •  0
  •   Jared    15 年前

    您也可以从主体对象继承来处理这个问题,无论您希望如何处理。

    以下是我在具有如下自定义规则的应用程序中所做的操作:

    创建了我自己的iprincipal对象,该对象是我的“person”对象的后代,可以继承查找组和角色等的能力:

    public class Principal : MyNamespace.Person, IPrincipal {
    }
    

    使当前上下文使用我的IPrincipal对象:

    protected void Application_AuthenticateRequest(Object Sender, EventArgs E) {
            if (HttpContext.Current.User != null &&
                HttpContext.Current.User.Identity.IsAuthenticated &&
                HttpContext.Current.User.Identity is FormsIdentity) {
                    FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
                    HttpContext.Current.User = new MyNamespace.Principal(id);
            } 
        }
    

    然后我创建了静态方法,这样我就不必每次都像这样为当前用户进行强制转换:

    public class CurrentUser {
    
            /// <summary>
            /// Is the current user authenticated
            /// </summary>
            static public bool IsAuthed {
                get { return System.Web.HttpContext.Current.User.Identity.IsAuthenticated; }
            }
    
            /// <summary>
            /// Returns the Principal object in case it is needed. Also used for other static properties of this class.
            /// </summary>
            static public MyNamespace.Principal User {
                get {
                    return (MyNamespace.Principal)System.Web.HttpContext.Current.User;
                }
            }
    }
    

    然后您可以调用像currentuser.user.isingroup()这样的东西。