【问题标题】:Render partial from different folder (not shared)从不同的文件夹渲染部分(不共享)
【发布时间】:2010-09-17 12:42:35
【问题描述】:

如何让视图呈现来自不同文件夹的部分(用户控件)? 在预览版 3 中,我曾经使用完整路径调用 RenderUserControl,但升级到预览版 5 后,这不再可能了。 相反,我们得到了 RenderPartial 方法,但它没有提供我正在寻找的功能。

【问题讨论】:

    标签: c# asp.net-mvc renderpartial


    【解决方案1】:

    只需包含视图的路径和文件扩展名。

    剃须刀:

    @Html.Partial("~/Views/AnotherFolder/Messages.cshtml", ViewData.Model.Successes)
    

    ASP.NET 引擎:

    <% Html.RenderPartial("~/Views/AnotherFolder/Messages.ascx", ViewData.Model.Successes); %>
    

    如果这不是您的问题,能否请您包含您用于使用 RenderUserControl 的代码?

    【讨论】:

    • 我希望我们可以说 /AnotherFolder/Messages
    • @Simon_Weaver 你可以做到这一点。一种方法是修改 ViewEngine 并用类似 if(partialViewName.Contains"/")partialViewName="~/Views/"+partialViewName; 的方法覆盖它的 FindPartialView 方法
    • 也可以在 MVC 3 Razor 引擎中使用,但是像上面一样,您需要扩展名 (.cshtml)。
    • 如果它在不同的是你需要给出路径“~/Areas/TestArea/Views/Shared/_SomePartial.mobile.cshtml”
    • 您如何处理该局部视图的不同文化(例如 ~/Views/AnotherFolder/Messages.en.cshtml)?
    【解决方案2】:

    在我的情况下,我使用 MvcMailer (https://github.com/smsohan/MvcMailer) 并希望从另一个文件夹访问部分视图,该文件夹不在“共享”中。上面的解决方案都不行,但是使用相对路径就行了。

    @Html.Partial("../MyViewFolder/Partials/_PartialView", Model.MyObject)
    

    【讨论】:

    • 类似@Html.Partial("../Shared/_PartialView") 使用共享文件夹。
    • 我发现如果最后没有 .cshtml 扩展名,这是行不通的。
    【解决方案3】:

    如果您经常使用此其他路径,则可以永久修复此问题,而无需一直指定路径。默认情况下,它会检查 View 文件夹和 Shared 文件夹中的部分视图。但是说你想加一个。

    向您的模型文件夹添加一个类:

    public class NewViewEngine : RazorViewEngine {
    
       private static readonly string[] NEW_PARTIAL_VIEW_FORMATS = new[] {
          "~/Views/Foo/{0}.cshtml",
          "~/Views/Shared/Bar/{0}.cshtml"
       };
    
       public NewViewEngine() {
          // Keep existing locations in sync
          base.PartialViewLocationFormats = base.PartialViewLocationFormats.Union(NEW_PARTIAL_VIEW_FORMATS).ToArray();
       }
    }
    

    然后在您的 Global.asax.cs 文件中,添加以下行:

    ViewEngines.Engines.Add(new NewViewEngine());
    

    【讨论】:

    • 当然我知道这个问题很久以前就被问过了。我想我会为未来的 Google 员工和未来的 Bingers 添加它。
    • - 在 .Net Core 2.2 中不起作用,因为 RazorViewEngine.PartialViewLocationFormats 不存在。
    【解决方案4】:

    对于使用 ASP.NET Core 2.1 或更高版本并希望使用Partial Tag Helper 语法的读者,试试这个:

    <partial name="~/Views/Folder/_PartialName.cshtml" />
    

    波浪号 (~) 是可选的。

    https://docs.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-3.1#partial-tag-helper 的信息也很有帮助。

    【讨论】:

      【解决方案5】:

      对于位于 Views/Account 文件夹中名为 myPartial.ascx 的用户控件,如下所示:

      <%Html.RenderPartial("~/Views/Account/myPartial.ascx");%>
      

      【讨论】:

        【解决方案6】:

        我创建了一个似乎运行良好的解决方法。我发现需要切换到不同控制器的上下文以进行操作名称查找、视图查找等。为了实现这一点,我为HtmlHelper 创建了一个新的扩展方法:

        public static IDisposable ControllerContextRegion(
            this HtmlHelper html, 
            string controllerName)
        {
            return new ControllerContextRegion(html.ViewContext.RouteData, controllerName);
        }
        

        ControllerContextRegion 定义为:

        internal class ControllerContextRegion : IDisposable
        {
            private readonly RouteData routeData;
            private readonly string previousControllerName;
        
            public ControllerContextRegion(RouteData routeData, string controllerName)
            {
                this.routeData = routeData;
                this.previousControllerName = routeData.GetRequiredString("controller");
                this.SetControllerName(controllerName);
            }
        
            public void Dispose()
            {
                this.SetControllerName(this.previousControllerName);
            }
        
            private void SetControllerName(string controllerName)
            {
                this.routeData.Values["controller"] = controllerName;
            }
        }
        

        它在视图中的使用方式如下:

        @using (Html.ControllerContextRegion("Foo")) {
            // Html.Action, Html.Partial, etc. now looks things up as though
            // FooController was our controller.
        }
        

        如果您的代码要求不更改 controller 路由组件,这可能会产生不必要的副作用,但到目前为止,在我们的代码中,这种方法似乎没有任何负面影响。

        【讨论】:

          【解决方案7】:

          WebFormsViewEngine 所基于的 VirtualPathProviderViewEngine 应该支持路径前面的“~”和“/”字符,因此您上面的示例应该可以工作。

          我注意到您的示例使用路径“~/Account/myPartial.ascx”,但您提到您的用户控件位于 Views/Account 文件夹中。你试过了吗

          &lt;%Html.RenderPartial("~/Views/Account/myPartial.ascx");%&gt;

          或者这只是你的问题中的一个错字?

          【讨论】:

            【解决方案8】:

            你应该试试这个

            ~/Views/Shared/parts/UMFview.ascx
            

            ~/Views/ 放在您的代码之前

            【讨论】:

              【解决方案9】:

              创建一个自定义视图引擎并拥有一个返回 ViewEngineResult 的方法 在此示例中,您只需覆盖 _options.ViewLocationFormats 并添加您的文件夹目录 :

              public ViewEngineResult FindView(ActionContext context, string viewName, bool isMainPage)
                      {
                          var controllerName = context.GetNormalizedRouteValue(CONTROLLER_KEY);
                          var areaName = context.GetNormalizedRouteValue(AREA_KEY);
              
                          var checkedLocations = new List<string>();
                          foreach (var location in _options.ViewLocationFormats)
                          {
                              var view = string.Format(location, viewName, controllerName);
                              if (File.Exists(view))
                              {
                                  return ViewEngineResult.Found("Default", new View(view, _ViewRendering));
                              }
                              checkedLocations.Add(view);
                          }
              
                          return ViewEngineResult.NotFound(viewName, checkedLocations);
                      }
              

              示例:https://github.com/AspNetMonsters/pugzor

              【讨论】:

                【解决方案10】:

                尝试使用RenderAction("myPartial","Account");

                【讨论】:

                • 请阅读问题,因为用户询问不同文件夹中的视图,您的代码中的文件夹在哪里?
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-05-10
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-08-27
                • 1970-01-01
                相关资源
                最近更新 更多