【问题标题】:Custom user in ASP.NET MVC 2ASP.NET MVC 2 中的自定义用户
【发布时间】:2010-07-26 11:21:50
【问题描述】:

我正在尝试在 ASP.NET MVC 2 中实现自定义用户对象。我看到了一个解决方案,您可以在 Global.asax 中做一些魔术来将 Controller.User 转换为另一种类型,比如 CustomUser。但是 Controller.User 仍然是一个 IPrincipal ,这意味着我每次要使用它时都必须将其强制转换为 CustomUser ,我一点也不喜欢这样。

拥有一个带有 GetUser() 方法的基本控制器,其中 GetUser() 调用用户存储库,并使用 Controller.User 获取我们自己的自定义用户对象,这会被认为是错误的还是不好的做法?

我要做的只是向用户对象添加几个属性。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-2


    【解决方案1】:

    会被认为是错误的还是坏的 练习,拥有一个基本控制器 使用 GetUser() 方法,其中 GetUser() 调用用户存储库,并且 使用 Controller.User 来获取我们自己的 自定义用户对象?

    我不这么认为。我就是这样做的。 ;)

    【讨论】:

    • 那如何避免使用this.User还是this.GetUser()的混淆呢? :)
    • @Anders Ekdahl,按返回类型。
    【解决方案2】:

    我会这样做:

    在 global.asax.cs 中

    protected void Application_PostAuthorizeRequest()
    {
        if (HttpContext.Current.User != null && HttpContext.Current.User.Identity != null && !string.IsNullOrEmpty(HttpContext.Current.User.Identity.Name))
        {
            HttpContext.Current.Items["User"] = userRepo.FetchByUsername(HttpContext.Current.User.Identity.Name);
        }
    }
    
    public static CustomUser CurrentUser
    {
        get
        {
            return HttpContext.Current.Items["User"] as CustomUser;
        }
    }
    

    那么你有一个方便的静态与当前用户在其中。这是一种肮脏但有效的方法。

    当然,我真的会将用户添加到我的 IOC 容器中,并通过启用 IOC 的 ControllerFactory 将其注入我的控制器中。这是“正确”的做法。

    无论你做什么,都不要使用基类!从长远来看,使用静态可能比创建一个包含您需要掌握的所有“方便”事物的巨大基类更易于维护。

    【讨论】:

    • 对我来说,静态调用比基类更糟糕。我同意你的观点,我不喜欢庞大的基类,但我们所有的控制器都需要与当前用户交互。基类只会获得从 IoC 注入的 UserLoader,而 GetUser() 方法只会将该调用代理到加载器。
    • 有一天您最终会在大多数(但不是所有)控制器中需要另一项服务。然后一些 wag 无论如何都会将它添加到基类中,瞧!怪物基类诞生!如果你想“正确”地做到这一点,请使用 ControllerFactory。 code.google.com/p/autofac/wiki/MvcIntegration
    • 我已经在使用控制器工厂,并使用 StructureMap 来注入依赖项。我不喜欢注入用户对象,但我可以很好地注入 UserLoader。但是我的所有控制器都将依赖于 UserLoader 类、User 类以及 UserLoader.Load() 采用 Controller 对象这一事实。相反,我的控制器只依赖 this.GetUser() 返回一个用户。
    • 只注入用户。你不会后悔的。此外,比基类更容易测试。
    【解决方案3】:

    这就是这样做的方法,但是您希望尽量减少转换用户对象所需的数量,以尽量减少违反 Liskov 替换原则:http://en.wikipedia.org/wiki/Solid_%28object-oriented_design%29

    不是每次都投射,有什么东西可以埋在 ActionFilter 中吗?

    【讨论】:

    • 您说“这就是这样做的方式”,但您的意思是哪种方式? :) 听起来您的意思是将自定义用户注入 Controller.User。我同意这听起来像是最好的解决方案,但我不知道如何避免那些讨厌的演员表。
    • 哎呀,我应该更清楚,我的意思是使用你提到的基类和 GetUser 方法。我的观点是尽量减少铸造的需要,例如如果您总是投射以获取用户的角色,那么您可以在操作过滤器中执行此操作并隐藏您使用自定义对象的速度。如果你真的需要自定义用户对象,那么考虑创建一个返回自定义用户的 IUserService 并通过你的 IoC 容器注入它(你可以在 BaseController 上声明它)。这样代码是可测试的,你没有演员表
    • 好吧,我没有在基本控制器中使用 GetUser() 进行任何强制转换。仅当您需要 Controller.User 中的自定义对象时,才需要进行强制转换,因为它是输入到 IPrincipal 的。现在,我有一个基本控制器,它有一个 IdentityLoader,它是在 IoC 构造控制器之后设置的。基本控制器有一个 GetIdentity() 方法,如果它还没有被调用,它只会调用 IdentityLoader.Load()。
    猜你喜欢
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    相关资源
    最近更新 更多