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

Lim*_*ing 14 razor asp.net-mvc-4

你好Razor MVC大师:

新手问题.

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

   MyIdentity myIdentity = (MyIdentity)((GenericPrincipal)context.User).Identity;
   MyComplexUser user = myIdentity.User;
   //user.name //user.location //user.username  //etc
Run Code Online (Sandbox Code Playgroud)

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

  • 主布局
  • 一些子级嵌套布局
  • 一些偏见
  • 一些观点

它实际上取决于视图所需的"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是一种矫枉过正的做法?

谢谢.再说一遍,我是MVC 4的新手,任何建议都非常感激.

And*_*lil 21

我会解释一个类似的解决方案,对我来说效果很好.通过微小的变化,我相信它对您(以及其他人,希望如此)也有效.

基本上,我们将使用继承.

控制器

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

public class BaseController : Controller
Run Code Online (Sandbox Code Playgroud)

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

public class HomeController : BaseController
Run Code Online (Sandbox Code Playgroud)

模型(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!
}
Run Code Online (Sandbox Code Playgroud)

OnActionExecuted被称为动作的执行,但之前的视图渲染.这正是我们想要的.

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