0

我的用户已通过身份验证,但在 FormsAuthenticationTicket 和 cookie 中存储了额外信息。

// Custom UserData will contain the following | seperated values:
// [ FullName | ContactNumber1 | ContactNumber2 ]
string userData = fullName + "|" + contactNumber1 + "|" + contactNumber2

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
                                                1,
                                                userName,
                                                DateTime.Now,
                                                DateTime.Now.AddMinutes(20),
                                                false,
                                                userData,
                                                FormsAuthentication.FormsCookiePath);

创建 Cookie 等

所有这一切都很好。

我正在使用 mvc 3 和 Razor

我有一个 foo.Layout.cshtml,它在页面顶部显示 Fullname / ContactNumber 等。

我可以在 foo.Layout.cshtml 的顶部包含代码来提取显示这些值:

@{

    FormsAuthenticationTicket ticket = ( (FormsIdentity)User.Identity ).Ticket;

    // Custom UserData will contain the following | seperated values:

    // [ FullName | ContactNumber1 | ContactNumber2 ]

    string[] userData = ticket.UserData.Split(new char[] { '|' });

    string fullName = userData[0];

    string contactNumber1 = userData[1];

    string contactNumber2 = userData[2];

}

<div>@fullName</div>

<div>@contactNumber1</div>

<div>@contactNumber2</div>

这意味着我不必在我的控制器中包含此代码,但老实说我不喜欢它,并且在我的实际应用程序(不同的值)中,我需要大多数视图中的值,包括布局。

所以我一直在讨论在我的控制器中包含代码:

创建一个视图模型:

public class UserViewModel {

    public string FullName { get; set; }

    public string ContactNumber1 { get; set; }

    public string ContactNumber2 { get; set; }

}

创建控制器

public class FooController : Controller {

    private readonly _userViewModel = null;

    public FooController( ) {

      // NOTE this would actually be behind an interface in some type of 
      //      repository / service pattern and injected but for the sake 
      //      of easy conversation ive put it here.

      FormsAuthenticationTicket ticket = ( (FormsIdentity)User.Identity ).Ticket;

      // Custom UserData will contain the following | seperated values:
      // [ FullName | ContactNumber1 | ContactNumber2 ]
      string[] userData = ticket.UserData.Split(new char[] { '|' });

      _userViewModel = new UserViewModel();

      userViewModel.FullName = userData[0];
      userViewModel.ContactNumber1 = userData[1];
      userViewModel.ContactNumber2 = userData[2];

    }

    public ActionResult Index() {

        (HOWEVER_SET_ON_LAYOUT_PAGE) = userViewModel.FullName;

        // If not posting ViewModel            
        (HOWEVER_SET_ON_THIS_PAGE) = userViewModel.FullName;

        // If posting ViewModel
        return View(_userViewModel);

    }

也许其中一些可以放在控制器工厂内。

我只是在寻找关于其他人如何接近这个非常常见的设置的讨论或想法。

我的实际任务是通过布局在每个页面的顶部显示用户全名,并在正在填写然后提交的各种表单的底部显示全名(和其他数据)。回发后,将从 cookie 中重新读取全名并将其发送到与其他表单字段一起存储。这有意义吗,真的是那个时候吗:-/

4

1 回答 1

0

在最近的项目中,我已经多次解决了这个问题。

比将它放在控制器中更好的是创建一个包装您的 FormsAuthentication 特定代码的身份验证服务,然后通过 IoC 在您可能需要的地方注入该服务。几乎任何 IoC 容器都应该能够指定您的身份验证服务可以按 http 请求进行缓存,因此您可以利用它来帮助节省资源/提高性能。

现在,如果您需要在很多地方显示此用户信息,我鼓励您创建一个单独的 UserController 并在视图中需要用户信息的任何地方对其进行 RenderAction 调用,而不是让您的用户视图模型成为一堆其他视图模型(除非其他模型/视图实际上需要它来满足某些业务条件等)。通过这种方式,您可以拥有用户信息的标准“规范”视图,作为一个组件,并且您可以从中获得大量重用。

于 2011-02-11T03:07:09.833 回答