如何以面向对象的方式显示不同的视图部分

时间:2009-06-27 14:49:57

标签: asp.net-mvc design-patterns

我正在ASP.NET MVC中开发一个网站,我希望为具有不同安全级别的用户显示视图的不同部分。从本质上讲,视图是相同的,但具有更高安全级别的用户必须能够看到安全级别高于(例如,管理员)的用户不应该看到的部分。

我不知道如何以面向对象的方式做到这一点。我认为这可以通过继承完成,但我不知道如何在视图中实现继承。

另外,我知道我可以编写很多ifs,做类似

的事情
<% if (User has some security level) { %>
   <span>show this info</span>
<% } %>

但这闻起来不太好。事实是我不知道如何使用面向对象的原则或设计来完成这项任务。

我认为这是一项常见任务,所以我认为有一种模式可以完成这项任务。例如,Stackoverflow在为发布问题(或答案或评论)的用户显示一些选项(编辑,删除等)并向其他人隐藏相同选项时执行此操作。

4 个答案:

答案 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();
    }
}