【发布时间】:2011-03-22 18:05:37
【问题描述】:
我是 ASP.net MVC 的新手,我想使用一个视图,但根据用户角色使用不同的母版页。
目前,如果用户在 Role1 并且 View2 在 中,我倾向于使用返回 View1 的控制器>角色2。 View1 和 View2 包含相同的局部视图,用于呈现两者共享但具有不同母版页的内容。
我想知道这是否是一种好的做法,或者您是否推荐其他设计。我的解决方案似乎有点复杂,做一些简单的事情。也许我错过了什么
谢谢!
【问题讨论】:
我是 ASP.net MVC 的新手,我想使用一个视图,但根据用户角色使用不同的母版页。
目前,如果用户在 Role1 并且 View2 在 中,我倾向于使用返回 View1 的控制器>角色2。 View1 和 View2 包含相同的局部视图,用于呈现两者共享但具有不同母版页的内容。
我想知道这是否是一种好的做法,或者您是否推荐其他设计。我的解决方案似乎有点复杂,做一些简单的事情。也许我错过了什么
谢谢!
【问题讨论】:
您可以有一个函数根据用户角色返回主名称,然后编写一个自定义操作过滤器,该过滤器将在操作后执行并根据当前连接的用户角色设置相应的母版页:
public class MasterChooserAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
var result = filterContext.Result as ViewResult;
if (result != null)
{
var user = filterContext.HttpContext.User;
result.MasterName = GetMaster(user);
}
}
private string GetMaster(IPrincipal user)
{
// TODO: based on the current user roles return the proper master page
throw new NotImplementedException();
}
}
然后简单地用这个动作过滤器装饰你的基本控制器,或者如果这是一个 ASP.NET MVC 3 应用程序,只需将它声明为global filter。
【讨论】:
Layout = ... 可以在_ViewStart 中工作,但这里我们讨论的是一个我不想留在视图中的重要逻辑。更不用说编写相同数量的代码了。另一个优点是,无论您使用什么视图引擎,它都可以工作,而 _ViewStart 和 Layout 是 Razor 特定的。
只需在您的视图中选择布局。 您可以在 mvc 3 中动态更改 @{Layout = XXX}。 见:http://weblogs.asp.net/scottgu/archive/2010/10/22/asp-net-mvc-3-layouts.aspx
您的控制器可以检查角色并分配要使用的布局,然后将其分配给视图中的@Layout,但您也可以将此代码保留在视图中以确定要使用的布局,因为毕竟这是“视图逻辑”
【讨论】:
选择母版页的方法有很多种,各有千秋。
最简单的可能是使用控制器 View 方法返回母版页名称
public ViewResult Index() {
var masterName = getMasterPageNameForUser(); //get you master page/layout name here
return View("Index", masterName, model);
}
但是这会导致一些重复的代码,因此另一种方法是创建一个自定义 IViewEngine 并在那里设置主名称。 Scott Hanselman's post 和 this coder journal post 将让您了解如何创建自定义视图引擎。从那里开始设置主名称。
【讨论】:
如果你想出第三个角色会发生什么?第四个角色?如果母版页根据其角色显示不同的内容,而不是将这种逻辑放入您的控制器中,该怎么办?您可以在主文件中隐藏整块 <div> 或诸如此类的东西。然后,只要角色依赖关系发生变化,您就只有一个地方可以更改它。母版页是否会因角色而有所不同?
【讨论】:
在你的控制器里做
this.ViewBag.Layout = something
在你看来
Layout = this.ViewBag.Layout
【讨论】: