268

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

4

10 回答 10

467

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

剃刀:

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

ASP.NET 引擎:

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

如果这不是您的问题,能否请您包含您曾经与 RenderUserControl 一起使用的代码?

于 2008-10-16T13:02:06.203 回答
33

In my case I was using MvcMailer (https://github.com/smsohan/MvcMailer) and wanted to access a partial view from another folder, that wasn't in "Shared." The above solutions didn't work, but using a relative path did.

@Html.Partial("../MyViewFolder/Partials/_PartialView", Model.MyObject)
于 2013-01-02T16:13:17.667 回答
29

If you are using this other path a lot of the time you can fix this permanently without having to specify the path all of the time. By default, it is checking for partial views in the View folder and in the Shared folder. But say you want to add one.

Add a class to your Models folder:

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

Then in your Global.asax.cs file, add the following line:

ViewEngines.Engines.Add(new NewViewEngine());
于 2015-03-11T16:04:26.507 回答
8

For readers using ASP.NET Core 2.1 or later and wanting to use Partial Tag Helper syntax, try this:

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

The tilde (~) is optional.

The information at https://docs.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-3.1#partial-tag-helper is helpful too.

于 2020-04-15T15:12:39.210 回答
7

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

<%Html.RenderPartial("~/Views/Account/myPartial.ascx");%>
于 2010-06-27T08:49:22.940 回答
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.
}

There may be unwanted side effects for this if your code requires the controller route component to not change, but in our code so far, there doesn't seem to be any negatives to this approach.

于 2012-09-13T00:51:55.040 回答
4

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

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

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

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

于 2008-10-20T23:52:21.817 回答
0

你应该试试这个

~/Views/Shared/parts/UMFview.ascx

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

于 2011-01-09T12:38:48.763 回答
0

Create a Custom View Engine and have a method that returns a ViewEngineResult In this example you just overwrite the _options.ViewLocationFormats and add your folder directory :

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

Example: https://github.com/AspNetMonsters/pugzor

于 2019-06-04T12:50:42.473 回答
-5

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

于 2011-05-31T00:09:22.960 回答