MVC:动态ascx在视图中加载

时间:2011-04-25 07:36:30

标签: asp.net-mvc asp.net-mvc-2 asp.net-mvc-3

我正在建立一个基本上具有相同模型的网站,不同之处在于视图。如果用户A登录,他将看到视图A.如果用户B登录,他将看到视图B.对于整个站点的大多数页面将是这样的。我读了一篇帖子,说我使用了区域。但由于我对这些页面有相同的模型,我想只使用一个控制器,控制器将确定要加载的视图。我想只使用一个aspx视图,然后根据用户加载ascx页面。我不想在我的视图中使用if语句来确定要呈现的ascx,执行此操作的最佳方法是什么?

谢谢!

3 个答案:

答案 0 :(得分:0)

在控制器中,您决定要显示哪个ASCX视图,并将其作为ViewModel的一部分或在ViewData中传递

if (UserA)
{
   ViewData["thePartialView"] = "NameOfPartialViewForUserA"
}
else 
{
   ViewData["thePartialView"] = "NameOfPartialViewForUserB"
}

在视图>

Html.RenderPartial(ViewData["thePartialView"]);

答案 1 :(得分:0)

我使用ViewEngine在views文件夹的子目录中搜索。在示例中,UserA将从UserA目录获得视图服务,如果该视图不存在,它将获得正常视图。

如果Views目录如下所示:

Views
|-> Home
|   |-> Index.cshtml
|   |-> UserA
|       |-> Index.cshtml
|-> Test
    |-> Index.cshtml

然后UserA将从Views / Home / UserA / Index.cshtml获取视图,其他人将获得Views / Home / Index.cshtml。包括UserA在内的所有人都会收到/Views/Test/Index.cshtml,因为UserA没有特定的服务。

    public class MyViewEngine : WebFormViewEngine
    {
        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            ViewEngineResult result = null;
            var request = controllerContext.HttpContext.Request;

            if (UserA)
            {
                result = base.FindView(controllerContext, "UserA/" + viewName, masterName, useCache);
            }

            //Fall back to normal view if no other view has been selected
            if (result == null || result.View == null)
            {
                result = base.FindView(controllerContext, viewName, masterName, useCache);
            }

            return result;
        }

        public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
        {
            ViewEngineResult result = null;
            var request = controllerContext.HttpContext.Request;

            if (UserA)
            {
                result = base.FindPartialView(controllerContext, "UserA/" + partialViewName, useCache);
            }

            //Fall back to normal view if no other view has been selected
            if (result == null || result.View == null)
            {
                result = base.FindPartialView(controllerContext, partialViewName, useCache);
            }

            return result;
        }
    }

答案 2 :(得分:0)

感谢您的回复。这是我的问题的解决方案,但我不知道它是否是最好的。

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var action = filterContext.Result as ViewResult;
        if (action != null)
        {
            action.MasterName = ViewData["siteConstants"].ToString();
        }

        base.OnActionExecuted(filterContext);
    }

这样的事情。我刚刚更改了action.MasterName行。在我的基本控制器的Initialize方法中,根据用户的不同,我为ViewData [“siteConstants”]指定了一个值,这是主页面的名称。我还使用了一个customViewEngine,其中我指定了我的母版页的自定义路径。