新手问题
背景.我有一个自定义的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,但是
>我不喜欢使用ViewBag.我喜欢强类型的对象
>如果我使用强类型的对象(“MyUser”)作为视图,那么我必须使用“MyUser”属性来流行所有这些模型.感觉有点脏吗?我喜欢保持我的模型干净,并具体到他们参与的观点.此外,它会不必要地重复.
>在像master_layout.cshtml或局部视图这样的地方,如果我把它放在控制器中,你如何访问“MyUser”?
>使用RenderAction并为每个User属性构建部分视图是一种过度的杀伤力?
谢谢.再次,我是MVC 4的新手,任何建议都非常感谢.
解决方法
基本上,我们将使用继承.
控制器
我们创建一个自定义的基本控制器,如
public class BaseController : Controller
让我们改变我们的控制器来继承它
public class HomeController : BaseController
模型(viewmodels,我说)
你的Models文件夹里可能有很多类,对吧?他们作为DTO从控制器到意见,对?
如果您对两者都回答“是”,请继续阅读.
让我们创建一个基础模型类,如公共类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在执行操作之后但在视图呈现之前被调用.这正是我们想要的.
我希望你已经有了. =)