从不同的文件夹渲染部分(不共享)

本文关键字:染部 共享 文件夹 | 更新日期: 2023-09-27 17:47:47

如何让视图从不同的文件夹渲染部分(用户控件)?对于预览3,我曾经用完整的路径调用RenderUserControl,但随着升级到预览5,这已经不可能了。相反,我们得到了RenderPartial方法,但它并没有为我提供我想要的功能。

从不同的文件夹渲染部分(不共享)

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

剃刀:

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

ASP。NET引擎:

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

如果这不是你的问题,你能不能包括你过去使用RenderUserControl的代码?

在我的案例中,我使用的是MvcMailer(https://github.com/smsohan/MvcMailer)并且希望从另一个文件夹访问不在"共享"中的部分视图。上述解决方案不起作用,但使用相对路径起作用。

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

如果你经常使用这个其他路径,你可以永久修复它,而不必一直指定路径。默认情况下,它在"视图"文件夹和"共享"文件夹中检查局部视图。但是说你想加一个。

在Models文件夹中添加一个类:

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());

适用于使用ASP的读者。NET Core 2.1或更高版本,并且想要使用Partial Tag Helper语法,请尝试以下操作:

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

波浪号(~)是可选的。

上的信息https://learn.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-3.1#部分标签助手也很有用。

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

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

我创建了一个似乎运行良好的变通方法。我发现需要切换到不同控制器的上下文中进行操作名称查找、视图查找等。为了实现这一点,我为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路由组件不更改,则可能会产生不必要的副作用,但到目前为止,在我们的代码中,这种方法似乎没有任何负面影响。

WebFormsViewEngine所基于的VirtualPathProviderViewEngine应该支持路径前面的"~"answers"/"字符,因此上面的示例应该可以使用。

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

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

或者这只是你问题中的一个拼写错误?

你应该试试这个

~/Views/Shared/parts/UMFview.ascx

~/Views/放在代码之前

创建一个自定义视图引擎并有一个返回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

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