Razor MVC,在哪里放置可在主页,partiview和view中访问的全局变量?

时间:2013-06-07 14:13:50

标签: asp.net-mvc-4 razor

Hello Razor MVC Gurus:

新手问题。

背景。我有一个自定义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)。用户))。名称)

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

  1. 我不喜欢使用ViewBag。我更喜欢强类型对象
  2. 如果我对视图使用强类型对象(“MyUser”),那么我必须使用“MyUser”属性来使用所有那些模型。感觉有点脏?因为我喜欢保持我的模型清洁,并且特定于他们所涉及的视图。此外,它会不必要地重复。
  3. 在master_layout.cshtml或partialviews等地方,如果我将它们放入控制器,你如何访问“MyUser”?
  4. 使用RenderAction并为每个User属性构建partialview是一种过度杀伤吗?
  5. 感谢。再说一遍,我是MVC 4的新手,任何建议都非常感激。

1 个答案:

答案 0 :(得分:21)

我将解释一个类似的解决方案,对我来说效果很好。通过微小的更改,我相信它也适用于您(以及其他人,希望如此)。

基本上,我们将使用继承

控制器

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

public class BaseController : Controller

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

public class HomeController : BaseController

模型(ViewModels,我说)

你的Models文件夹中可能有很多类,对吗?它们充当从控制器到视图的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被称为,而在视图呈现之前被称为。这正是我们想要的。

我希望你已经得到了它。 =)