Teilweise aus einem anderen Ordner rendern (nicht freigegeben)


256

Wie kann ich eine Ansicht einen Teil (Benutzersteuerung) aus einem anderen Ordner rendern lassen? Mit Vorschau 3 habe ich RenderUserControl mit dem vollständigen Pfad aufgerufen, aber mit einem Upgrade auf Vorschau 5 ist dies nicht mehr möglich. Stattdessen haben wir die RenderPartial-Methode, die mir jedoch nicht die gesuchte Funktionalität bietet.

Antworten:


443

Fügen Sie einfach den Pfad zur Ansicht mit der Dateierweiterung hinzu.

Rasierer:

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

ASP.NET-Engine:

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

Wenn dies nicht Ihr Problem ist, können Sie bitte Ihren Code einfügen, der früher mit RenderUserControl funktioniert hat?


19
Ich wünschte, wir könnten einfach / AnotherFolder / Messages
Simon_Weaver

4
@ Simon_Weaver Das können Sie erreichen. Eine Möglichkeit wäre, ViewEngine zu ändern und seine FindPartialViewMethode mit etwas wieif(partialViewName.Contains"/")partialViewName="~/Views/"+partialViewName;
Arnis Lapsa

2
Funktioniert auch in der MVC 3 Razor-Engine, aber wie oben benötigen Sie die Erweiterung (.cshtml).
Chris

Wenn es unter verschiedenen ist, müssten Sie Pfad "~ / Areas / TestArea / Views / Shared / _SomePartial.mobile.cshtml"
Sandeep Talabathula

Wie gehen Sie mit verschiedenen Kulturen dieser Teilansicht um (z. B. ~ / Views / AnotherFolder / Messages.en.cshtml)?
Jasdefer

29

In meinem Fall habe ich MvcMailer (https://github.com/smsohan/MvcMailer) verwendet und wollte auf eine Teilansicht aus einem anderen Ordner zugreifen, der nicht in "Shared" enthalten war. Die oben genannten Lösungen haben nicht funktioniert, aber die Verwendung eines relativen Pfads hat funktioniert.

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

Ebenso @ Html.Partial ("../ Shared / _PartialView"), um den Shared-Ordner zu verwenden.
Curtis Yallop

11
Ich finde, dass dies ohne die Erweiterung .cshtml am Ende nicht funktioniert.
Luke

28

Wenn Sie diesen anderen Pfad häufig verwenden, können Sie dies dauerhaft beheben, ohne den Pfad ständig angeben zu müssen. Standardmäßig wird im Ordner "Ansicht" und im Ordner "Freigegeben" nach Teilansichten gesucht. Angenommen, Sie möchten eine hinzufügen.

Fügen Sie Ihrem Modellordner eine Klasse hinzu:

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

Fügen Sie dann in Ihrer Datei Global.asax.cs die folgende Zeile hinzu:

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

6
Natürlich ist mir klar, dass diese Frage vor langer Zeit gestellt wurde. Ich dachte, ich würde es für zukünftige Googler und zukünftige Binger ergänzen.
Paul

- Funktioniert in .Net Core 2.2 nicht, da RazorViewEngine.PartialViewLocationFormats nicht vorhanden ist.
Demian Berisford-Maynard

7

Für ein Benutzersteuerelement mit dem Namen myPartial.ascx im Ordner Ansichten / Konto schreiben Sie Folgendes:

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

5

Ich habe eine Problemumgehung erstellt, die ziemlich gut zu funktionieren scheint. Ich habe festgestellt, dass für die Suche nach Aktionsnamen, die Suche nach Ansichten usw. in den Kontext eines anderen Controllers gewechselt werden muss. Um dies zu implementieren, habe ich eine neue Erweiterungsmethode erstellt für HtmlHelper:

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

ControllerContextRegion ist definiert als:

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

In einer Ansicht wird dies folgendermaßen verwendet:

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

Dies kann zu unerwünschten Nebenwirkungen führen, wenn Ihr Code erfordert, dass sich die controllerRoutenkomponente nicht ändert. In unserem Code scheint dieser Ansatz jedoch bisher keine negativen Auswirkungen zu haben.


4

Die VirtualPathProviderViewEngine, auf der die WebFormsViewEngine basiert, soll die Zeichen "~" und "/" am Anfang des Pfads unterstützen, damit die obigen Beispiele funktionieren.

Ich habe festgestellt, dass Ihre Beispiele den Pfad "~ / Account / myPartial.ascx" verwenden, aber Sie haben erwähnt, dass sich Ihr Benutzersteuerelement im Ordner "Ansichten / Konto" befindet. Hast du es versucht

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

oder ist das nur ein Tippfehler in deiner Frage?



0

Sie sollten dies versuchen

~/Views/Shared/parts/UMFview.ascx

Platzieren Sie das ~/Views/vor Ihrem Code


0

Erstellen Sie eine benutzerdefinierte View Engine und verfügen Sie über eine Methode, die ein ViewEngineResult zurückgibt. In diesem Beispiel überschreiben Sie einfach das _options.ViewLocationFormatsund fügen Ihr Ordnerverzeichnis hinzu:

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

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


-5

Versuchen Sie es mit RenderAction("myPartial","Account");


3
Bitte lesen Sie die Frage, während der Benutzer nach der Ansicht in einem anderen Ordner fragt. Wo befindet sich der Ordner in Ihrem Code?
Pamma
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.