Razor MVC,将可跨母版页、partiview 和视图访问的全局变量放在哪里? [英] Razor MVC, where to put global variables that's accessible across master page, partiview and view?

查看:24
本文介绍了Razor MVC,将可跨母版页、partiview 和视图访问的全局变量放在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好 Razor MVC 大师:

Hello Razor MVC Gurus:

新手问题.

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

Background. I have a custom IIdentity that is set in an HttpModule before it gets to controller & views. To use it, i have to do

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

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

The problem is, I use the object in different places such as

  • 主布局
  • 一些子级嵌套布局
  • 一些局部视图
  • 一些观点

这实际上取决于视图需要的MyComplexUser"对象的哪些属性.

It really depends on what properties of "MyComplexUser" object the views need.

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

Currently, in the views, I have to do this really complicated casting to get to a property. For instance, if I want the "Name" of the user, I need to do

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

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

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

I suppose I could put it in the controllers and then populate the ViewBag with a ViewBag.MyUser property, but then

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

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

Thanks. Again, I'm a newbie at MVC 4, any suggestion is greatly appreciate it.

推荐答案

我将解释一个对我来说非常有效的类似解决方案.我相信只要稍加改动,它就会对你(以及其他人,希望如此)有用.

I'll explain a similar solution that works pretty well for me. With small changes, I believe that it will work for you (and others, hopefully) as well.

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

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

Let's create a custom base controller, such as

public class BaseController : Controller

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

and let's change our controllers to inherit from it, as

public class HomeController : BaseController

模型(ViewModels,我说)

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

让我们创建一个基础模型类,比如public class BaseVM,然后让我们改变我们的模型来继承它,比如public class HomeIndex : BaseVM

Let's create a base model class, such as public class BaseVM, and let's change our models to inherit from it, like public class HomeIndex : BaseVM

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

Important: your layout file (_Layout or whatsoever) must be strongly typed to BaseVM or a child of it.

既然所有的东西都打得很漂亮,让我们使用对我们有利的请求管道.在 BaseController 中,您将添加如下所示的方法:

Now that everything's beautifuly typed, let's use the request pipeline in our favor. At BaseController, you'll add a method that looks like this:

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 在操作执行后但在视图渲染之前被调用.这正是我们想要的.

OnActionExecuted is called after the execution of the action but before the view rendering. That's exactly what we want.

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

I hope you got it already. =)

这篇关于Razor MVC,将可跨母版页、partiview 和视图访问的全局变量放在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆