【问题标题】:MVC: Dynamic ascx to load in a viewMVC:要在视图中加载的动态 ascx
【发布时间】:2011-04-25 07:36:30
【问题描述】:

我正在建立一个模型基本相同的网站,不同之处在于视图。如果用户 A 登录,他将看到视图 A。如果用户 B 登录,他将看到视图 B。对于整个站点的大多数页面来说,情况都是如此。我读了一篇文章,说我利用了区域。但由于我对这些页面有相同的模型,我正在考虑只使用一个控制器,控制器将确定要加载的视图。我想只使用一个 aspx 视图,然后根据用户加载 ascx 页面。我不想在我的视图中使用 if 语句来确定要渲染的 ascx,最好的方法是什么?

谢谢!

【问题讨论】:

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


    【解决方案1】:

    我使用在视图文件夹的子目录中搜索的 ViewEngine。在示例中,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】:

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

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

      在视图中>

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

      【讨论】:

        【解决方案3】:

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

            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,在其中我指定了我的母版页的自定义路径。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-10-07
          • 1970-01-01
          • 2011-01-04
          • 1970-01-01
          相关资源
          最近更新 更多