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


256

如何让视图呈现来自其他文件夹的部分(用户控件)?在预览版3中,我曾经使用完整路径调用RenderUserControl,但无法升级到预览版5。相反,我们得到了RenderPartial方法,但是它没有为我提供所需的功能。

Answers:


443

只需包括带有文件扩展名的视图路径即可。

剃刀:

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

ASP.NET引擎:

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

如果那不是您的问题,可以请您提供用于RenderUserControl的代码?


19
我希望我们可以说/ AnotherFolder / Messages
Simon_Weaver

4
@Simon_Weaver您可以实现。一种方法是修改ViewEngine并FindPartialView使用类似的方法覆盖它的方法if(partialViewName.Contains"/")partialViewName="~/Views/"+partialViewName;
Arnis Lapsa 2011年

2
也可以在MVC 3 Razor引擎中使用,但是像上面一样,您需要扩展名(.cshtml)。
克里斯(Chris

如果不同,则需要提供路径“〜/ Areas / TestArea / Views / Shared / _SomePartial.mobile.cshtml”
sandeep talabathula 2015年

您如何处理该局部视图的不同区域性(例如〜/ Views / AnotherFolder / Messages.en.cshtml)?
jasdefer

29

在我的情况下,我使用的是MvcMailer(https://github.com/smsohan/MvcMailer),想要从另一个不在“共享”文件夹中的文件夹访问局部视图。上面的解决方案不起作用,但是使用相对路径起作用。

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

类似地,@ Html.Partial(“ ../ Shared / _PartialView”)使用共享文件夹。
Curtis Yallop 2013年

11
我发现如果没有.cshtml扩展名,这将无法正常工作。
路加福音

28

如果您经常使用其他路径,则可以永久修复此问题,而不必始终指定路径。默认情况下,它将检查“视图”文件夹和“共享”文件夹中的部分视图。但是说您想添加一个。

将类添加到“模型”文件夹:

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

6
我当然知道这个问题是很久以前问过的。以为我会为将来的Google员工和未来的Bingers增加它。
Paul

-无法在.Net Core 2.2中工作,因为RazorViewEngine.PartialViewLocationFormats不存在。
Demian Berisford-Maynard

7

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

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

5

我创建了一种变通方法,似乎工作得很好。我发现需要切换到其他控制器的上下文以进行动作名称查找,视图查找等。为实现此目的,我为以下操作创建了新的扩展方法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路由组件保持不变,则可能会有不良的副作用,但是到目前为止,在我们的代码中,这种方法似乎没有任何负面影响。


4

WebFormsViewEngine所基于的VirtualPathProviderViewEngine应该在路径的开头支持“〜”和“ /”字符,因此上面的示例应该可以使用。

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

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

还是只是您输入的错字?



0

你应该试试这个

~/Views/Shared/parts/UMFview.ascx

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


0

创建一个自定义View Engine并具有返回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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.