我正在ASP.NET MVC中开发一个网站,我希望为具有不同安全级别的用户显示视图的不同部分。从本质上讲,视图是相同的,但具有更高安全级别的用户必须能够看到安全级别高于(例如,管理员)的用户不应该看到的部分。
我不知道如何以面向对象的方式做到这一点。我认为这可以通过继承完成,但我不知道如何在视图中实现继承。
另外,我知道我可以编写很多ifs,做类似
的事情<% if (User has some security level) { %>
<span>show this info</span>
<% } %>
但这闻起来不太好。事实是我不知道如何使用面向对象的原则或设计来完成这项任务。
我认为这是一项常见任务,所以我认为有一种模式可以完成这项任务。例如,Stackoverflow在为发布问题(或答案或评论)的用户显示一些选项(编辑,删除等)并向其他人隐藏相同选项时执行此操作。
答案 0 :(得分:0)
根据您正在执行的操作的复杂程度,if语句路由可能已足够。如果没有,那么您可以查看使用部分视图并编写HtmlHelper扩展,允许您基于特定角色渲染部分视图。它可能看起来像这样:
<% Html.RenderPartialWithRole( "AdminSection",
Model,
ViewData,
User,
"Administrator",
null ) %>
public static void RenderPartialWithRole( this HtmlHelper helper,
string partialName,
object model,
ViewDataDictionary viewData,
IPrincipal user,
string role,
object htmlAttributes )
{
if (user != null && !string.IsNullOrEmpty(role) && user.IsInRole(role))
{
helper.RenderPartial( partialName, model, viewData, htmlAttributes );
}
}
答案 1 :(得分:0)
使用强类型视图,在模型上有一个布尔属性,如ShowSection(每个部分一个,在控制器中设置逻辑)。将div中的部分用好的ID。然后使用JavaScript或jquery根据Boolean属性设置div标签显示样式。
答案 2 :(得分:0)
您可以将部分中的所有部分都包含在内,并构建视图以包含可用于不同权限级别的部分。所以一个用于管理员,一个用于每个级别。然后您的Controller具有决定使用哪个视图的逻辑。所以任何OO部分都在控制器中,而不是视图。
答案 3 :(得分:0)
这不是一种面向对象的方法,但它是相关的。这个问题的有趣部分是如何获得if语句。摆脱if或case的常用方法是使用标准和效果的查找表。还有其他技术使用同样的想法,例如数据导向编程(http://en.wikipedia.org/wiki/Data-directed___programming)和调度表(http://en.wikipedia.org/wiki/Dispatch_table)。许多语言实现使用类型调度表来实现虚方法调用。
假设部分视图可以解决此问题,则查找表可以是对列表。该对的第一个元素是用于检查当前用户的角色名称。该对的第二个元素是角色检查成功时要呈现的部分视图的名称。
我们在控制器(或者什么)中初始化表并将其分配给ViewData,然后使用Html.RenderViewByRole选择并呈现正确的局部视图:
<% Html.RenderPartialByRole(User, (List<Dispatch>)ViewData["rolePartial"]); %>
public static class MyHelper {
public static void RenderPartialByRole(this HtmlHelper helper, IPrincipal user, List<Dispatch> rolePartial) {
foreach (Dispatch d in rolePartial) {
if (d.CheckRole(user)) {
helper.RenderPartial(d.PartialName);
break;
}
}
}
}
public class Dispatch {
string _roleName;
string _partialName;
public Dispatch(string roleName, string partialName) {
_roleName = roleName;
_partialName = partialName;
}
public bool CheckRole(IPrincipal user) {
return user.IsInRole(_roleName);
}
public string PartialName {
get { return _partialName; }
}
}
public class HomeController : Controller {
List<Dispatch> rolePartial = new List<Dispatch>();
private void InitTable() {
rolePartial.Add(new Dispatch("admin", "adminPartial"));
rolePartial.Add(new Dispatch("report", "reportPartial"));
rolePartial.Add(new Dispatch("guest", "guestPartial"));
}
public HomeController() {
InitTable();
}
public ActionResult Index() {
ViewData["rolePartial"] = rolePartial;
return View();
}
}