我如何能有一个视图呈现部分(用户控件)从不同的文件夹? 有了预览3,我习惯用完整的路径调用RenderUserControl,但升级到预览5,这是不可能的了。 相反,我们得到了RenderPartial方法,但它没有提供我所寻找的功能。


当前回答

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

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

其他回答

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

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

对于使用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#partial-tag-helper上的信息也很有用。

我想出了一个变通办法,看起来效果不错。我发现需要切换到不同控制器的上下文进行动作名称查找、视图查找等。为了实现这一点,我为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.
}

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

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

剃须刀:

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

ASP。NET引擎:

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

如果这不是你的问题,你能包括你的代码,用来与RenderUserControl工作吗?