16

你好 Razor MVC 大师:

新手问题。

背景。我有一个自定义 IIdentity,它在进入控制器和视图之前在 HttpModule 中设置。要使用它,我必须这样做

   MyIdentity myIdentity = (MyIdentity)((GenericPrincipal)context.User).Identity;
   MyComplexUser user = myIdentity.User;
   //user.name //user.location //user.username  //etc

问题是,我在不同的地方使用对象,例如

  • 主布局
  • 一些子级嵌套布局
  • 部分观点
  • 一些看法

这实际上取决于视图需要的“MyComplexUser”对象的哪些属性。

目前,在视图中,我必须执行这个非常复杂的转换才能获得一个属性。例如,如果我想要用户的“姓名”,我需要做

@(((MyComplexUser)(((MyIdentity)((GenericPrincipal)context.User).Identity).User)).Name)

我想我可以把它放在控制器中,然后用 ViewBag.MyUser 属性填充 ViewBag,但是然后

  1. 我不喜欢使用 ViewBag。我更喜欢强类型对象
  2. 如果我对视图使用强类型对象(“MyUser”),那么我必须使用“MyUser”属性来流行所有这些模型。感觉有点脏?因为我喜欢让我的模型保持干净,并具体到他们所涉及的视图。此外,它会不必要地重复。
  3. 在 master_layout.cshtml 或 partialviews 之类的地方,如果我将它们放在控制器中,您如何访问“MyUser”?
  4. 使用 RenderAction 并为每个 User 属性构建局部视图是一种矫枉过正吗?

谢谢。同样,我是 MVC 4 的新手,任何建议都非常感谢。

4

1 回答 1

22

我将解释一个对我来说非常有效的类似解决方案。通过小的改动,我相信它也会对你(以及其他人,希望如此)有用。

基本上,我们将使用继承

控制器

让我们创建一个自定义的基本控制器,例如

public class BaseController : Controller

让我们改变我们的控制器来继承它,如

public class HomeController : BaseController

模型(我说的是 ViewModel)

您的模型文件夹中可能有很多类,对吧?它们充当从控制器到视图的 DTO,对吗?如果您对两者的回答都是肯定的,请继续阅读。

让我们创建一个基础模型类,例如public class BaseVM,让我们更改模型以从它继承,例如public class HomeIndex : BaseVM

重要提示:您的布局文件(_Layout或其他任何文件)必须是强类型文件BaseVM或其子文件。

钩子

现在所有的东西都输入得很漂亮,让我们使用对我们有利的请求管道。在 处BaseController,您将添加一个如下所示的方法:

protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
    if (filterContext.Result is ViewResultBase)//Gets ViewResult and PartialViewResult
    {
        object viewModel = ((ViewResultBase)filterContext.Result).Model;

        if (viewModel != null && viewModel is BaseVM)
        {
            BaseVM baseVM = viewModel as BaseVM;

            baseVM.MyIdentity = (MyIdentity)((GenericPrincipal)context.User).Identity;
            //and so on...
        }
    }

    base.OnActionExecuted(filterContext);//this is important!
}

OnActionExecuted在执行操作之后但视图渲染之前调用。这正是我们想要的。

我希望你已经明白了。=)

于 2013-06-07T15:17:19.863 回答