Razor MVC,将可跨母版页、partiview 和视图访问的全局变量放在哪里? [英] Razor MVC, where to put global variables that's accessible across master page, partiview and view?
问题描述
你好 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
- 我不喜欢使用 ViewBag.我更喜欢强类型对象
- 如果我对视图使用强类型对象(MyUser"),那么我必须使用MyUser"属性来流行所有这些模型.感觉有点脏?因为我喜欢保持我的模型干净并且特定于它们所涉及的视图.此外,它会不必要地重复.
- 在诸如 master_layout.cshtml 或 partialviews 之类的地方,如果我将它们放在控制器中,您如何访问MyUser"?
- 使用 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屋!